WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 1/4] (Refactored) provide vhd support to qemu
From: Ben Guthro <bguthro@xxxxxxxxxxxxxxx>
Date: Thu, 21 Jun 2007 13:27:39 -0400
Delivery-date: Thu, 21 Jun 2007 10:24:08 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 2.0.0.0 (X11/20070418)
[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
<Prev in Thread] Current Thread [Next in Thread>