[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 1/4] (Refactored) provide vhd support to qemu



[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.