[PATCH 1/4] (Refactored) provide vhd support to qemu
qemu-vhd-support.patch
Provides integration of vdisk library, and implementation of block-vhd
into qemu.
Signed-off-by: Boris Ostrovsky <bostrovsky@xxxxxxxxxxxxxxx>
Signed-off-by: Ben Guthro <bguthro@xxxxxxxxxxxxxxx>
diff -r 005dd6b1cf8e tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target Wed Jun 20 15:33:14 2007 +0100
+++ b/tools/ioemu/Makefile.target Thu Jun 21 13:04:26 2007 -0400
@@ -18,6 +18,8 @@ CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(S
CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH)
CPPFLAGS+= -I$(XEN_ROOT)/tools/libxc
CPPFLAGS+= -I$(XEN_ROOT)/tools/xenstore
+CPPFLAGS+= -I$(XEN_ROOT)/tools/vdisk -I$(XEN_ROOT)/tools/blktap/drivers
+CPPFLAGS+= -I$(XEN_ROOT)/tools/libaio/src
ifdef CONFIG_DARWIN_USER
VPATH+=:$(SRC_PATH)/darwin-user
CPPFLAGS+=-I$(SRC_PATH)/darwin-user -I$(SRC_PATH)/darwin-user/$(TARGET_ARCH)
@@ -198,6 +200,7 @@ LIBS+=-L../../libxc -lxenctrl -lxenguest
LIBS+=-L../../libxc -lxenctrl -lxenguest
LIBS+=-L../../xenstore -lxenstore
LIBS+=-lpthread
+LIBS+=-L$(XEN_ROOT)/tools/vdisk -lvdisk -L$(XEN_ROOT)/tools/libaio/src -laio
-ldl
ifndef CONFIG_USER_ONLY
LIBS+=-lz
endif
@@ -345,6 +348,7 @@ VL_OBJS+=cutils.o
VL_OBJS+=cutils.o
VL_OBJS+=block.o block-raw.o
VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o
block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o
+VL_OBJS+=block-vhd.o
ifdef CONFIG_WIN32
VL_OBJS+=tap-win32.o
endif
diff -r 005dd6b1cf8e tools/ioemu/block-vhd.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/block-vhd.c Thu Jun 21 13:04:31 2007 -0400
@@ -0,0 +1,186 @@
+// Copyright (c) 2003-2007, Virtual Iron Software, Inc.
+//
+// Portions have been modified by Virtual Iron Software, Inc.
+// (c) 2007. This file and the modifications can be redistributed and/or
+// modified under the terms and conditions of the GNU General Public
+// License, version 2.1 and not any later version of the GPL, as published
+// by the Free Software Foundation.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/stddef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <time.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "vl.h"
+#include "block_int.h"
+#include "exec-all.h" // for FILE* logfile
+
+#ifdef LIST_HEAD
+#undef LIST_HEAD // defined in audio/sys-queue.h (included via vl.h)
+#endif
+#include <vdisk.h>
+
+
+
+typedef struct BDRVVhdState {
+ vdisk_dev_t *vdisk;
+} BDRVVhdState;
+
+/*
+ * See whether the disk is in VHD format.
+ * XXX: We do it based on file siffix, which is silly.
+ * We should probably open it and try to read headers/footers.
+ */
+static int qemu_vhd_probe(const uint8_t *buf, int buf_size, const char
*filename)
+{
+ char *file_fmt;
+
+ // Find file suffix
+ file_fmt = strrchr(filename, '.');
+ if (file_fmt) {
+
+ file_fmt++; // Skip '.'
+
+ if (!strcmp(file_fmt, "vhd")) {
+ printf("Detected VHD file %s\n", filename);
+ return (100);
+ }
+ }
+ return 0;
+}
+
+static void qemu_vhd_close(BlockDriverState *bs)
+{
+ BDRVVhdState *s;
+
+ // We may be called more than once
+ // XXX: Or not?
+ if (bs == NULL)
+ return;
+
+ s = bs->opaque;
+ if ((s == NULL) || (s->vdisk == NULL))
+ return;
+
+ vdisk_fini(s->vdisk);
+ qemu_free(s->vdisk);
+ s->vdisk = NULL;
+}
+
+#if 1
+#define DEBUG_VHD_OPN_CLS_PRINT( formatCstr, args... ) fprintf( logfile,
formatCstr, ##args ); fflush( logfile )
+#else
+#define DEBUG_VHD_OPN_CLS_PRINT( formatCstr, args... )
+#endif
+
+static int qemu_vhd_open(BlockDriverState *bs, const char *filename)
+{
+ BDRVVhdState *s = bs->opaque;
+ struct program_props props;
+ int ret = 0;
+
+ DEBUG_VHD_OPN_CLS_PRINT("vhd_open(%s)\n", filename);
+
+ s->vdisk = qemu_malloc(sizeof(struct vdisk_dev));
+ if (s->vdisk == NULL) {
+ printf("Can't allocate memory for vdisk\n");
+ return (-ENOMEM);
+ }
+
+ props.alloc_func = qemu_malloc;
+ props.free_func = qemu_free;
+ props.out_target = VDISK_OUT_STDERR;
+ ret = vdisk_init(s->vdisk, (char *)filename, &props, 1);
+ if (ret) {
+ printf("Can't initialize vdisk for %s\n", filename);
+ qemu_free(s->vdisk);
+ goto out;
+ }
+
+ /* qemu does not use aio */
+ s->vdisk->aio_fd = -1;
+ s->vdisk->use_aio = 0;
+
+ // VHD format limits geometry to roughly 136GB (0xffff cylinders,
+ // 0x10 heads and 0xff sectors per cylinder). We'll report "original
+ // size" (as specified by the header), not CHS product
+ // (Note that currently QEMU doesn't support disks ober 127GB anyway.
+ // This change is made so that QEMU and tapdisk return consistent
+ // disk size)
+ bs->total_sectors = s->vdisk->sz >> 9;
+ printf("Disk size is %ld sectors\n", bs->total_sectors);
+
+ bs->read_only = 0; // XXX: Really?
+
+out:
+ if (ret>0)
+ ret *= -1; // Need to return negative number on error;
+
+ return ret;
+
+}
+
+static int qemu_vhd_read(BlockDriverState *bs, int64_t sector_num,
+ uint8_t *buf, int nb_sectors)
+{
+ BDRVVhdState *s = bs->opaque;
+ int res = 0;
+
+ res = vdisk_rw(s->vdisk, sector_num, buf,
+ nb_sectors, VDISK_READ, NULL);
+
+ // QEMU is not very consistent in how it treats return codes from
+ // bdrv_read()/bdrv_write(). Sometimes negative number is an error,
+ // sometimes it's a non-zero value. vdisk_rw() returns number of
+ // bytes that have been processed as syncIO
+ if (res >= 0)
+ res = 0;
+
+ return (res);
+}
+
+static int qemu_vhd_write(BlockDriverState *bs, int64_t sector_num,
+ const uint8_t *buf, int nb_sectors)
+{
+ BDRVVhdState *s = bs->opaque;
+ int res = 0;
+
+ res = vdisk_rw(s->vdisk, sector_num, (uint8_t *)buf,
+ nb_sectors, VDISK_WRITE, NULL);
+
+ // See comment in qemu_vhd_read()
+ if (res >= 0)
+ res = 0;
+
+ return (res);
+}
+
+static int qemu_vhd_create(const char *filename, int64_t total_size,
+ const char *backing_file, int flags)
+{
+ printf("Creating VHD disks is not supported\n");
+
+ return ENOTSUP;
+}
+
+BlockDriver bdrv_vhd = {
+ "vhd",
+ sizeof(BDRVVhdState),
+ qemu_vhd_probe,
+ qemu_vhd_open,
+ qemu_vhd_read,
+ qemu_vhd_write,
+ qemu_vhd_close,
+ qemu_vhd_create,
+ NULL, /* flush */
+ NULL, /* is_allocated */
+ NULL, /* set_key */
+ NULL /* make_empty */
+};
diff -r 005dd6b1cf8e tools/ioemu/block.c
--- a/tools/ioemu/block.c Wed Jun 20 15:33:14 2007 +0100
+++ b/tools/ioemu/block.c Thu Jun 21 13:04:08 2007 -0400
@@ -1246,6 +1246,7 @@ void bdrv_init(void)
bdrv_register(&bdrv_vpc);
bdrv_register(&bdrv_vvfat);
bdrv_register(&bdrv_qcow2);
+ bdrv_register(&bdrv_vhd);
}
void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
diff -r 005dd6b1cf8e tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Wed Jun 20 15:33:14 2007 +0100
+++ b/tools/ioemu/vl.c Thu Jun 21 13:04:08 2007 -0400
@@ -7223,14 +7223,23 @@ int main(int argc, char **argv)
case QEMU_OPTION_hdb:
case QEMU_OPTION_hdc:
case QEMU_OPTION_hdd:
- {
- int hd_index;
- hd_index = popt->index - QEMU_OPTION_hda;
- hd_filename[hd_index] = optarg;
- if (hd_index == cdrom_index)
- cdrom_index = -1;
- }
- break;
+ {
+ int hd_index;
+ char *fname;
+
+ fname = strchr(optarg, ':');
+ if (fname == NULL)
+ fname = optarg;
+ else
+ fname++;
+
+ hd_index = popt->index - QEMU_OPTION_hda;
+ hd_filename[hd_index] = fname;
+ if (hd_index == cdrom_index)
+ cdrom_index = -1;
+ }
+
+ break;
#endif /* !CONFIG_DM */
case QEMU_OPTION_snapshot:
snapshot = 1;
diff -r 005dd6b1cf8e tools/ioemu/vl.h
--- a/tools/ioemu/vl.h Wed Jun 20 15:33:14 2007 +0100
+++ b/tools/ioemu/vl.h Thu Jun 21 13:04:08 2007 -0400
@@ -589,6 +589,7 @@ extern BlockDriver bdrv_vpc;
extern BlockDriver bdrv_vpc;
extern BlockDriver bdrv_vvfat;
extern BlockDriver bdrv_qcow2;
+extern BlockDriver bdrv_vhd;
typedef struct BlockDriverInfo {
/* in bytes, 0 if irrelevant */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|