* [PATCH 2/4] provide vhd support to blktap
@ 2007-06-19 13:16 Ben Guthro
0 siblings, 0 replies; only message in thread
From: Ben Guthro @ 2007-06-19 13:16 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: Type: text/plain, Size: 263 bytes --]
[PATCH 2/4] provide vhd support to blktap
tapdisk-vhd-support.patch
Provides integration of vdisk library, and implementation of block-vhd
into blktap
Signed-off-by: Boris Ostrovsky <bostrovsky@virtualiron.com>
Signed-off-by: Ben Guthro <bguthro@virtualiron.com>
[-- Attachment #2: tapdisk-vhd-support.patch --]
[-- Type: text/x-patch, Size: 11452 bytes --]
diff -r 92f2f05d6839 tools/blktap/drivers/Makefile
--- a/tools/blktap/drivers/Makefile Tue Jun 19 08:00:26 2007 -0400
+++ b/tools/blktap/drivers/Makefile Tue Jun 19 08:00:26 2007 -0400
@@ -7,12 +7,14 @@ QCOW_UTIL = img2qcow qcow2raw qcow-cr
QCOW_UTIL = img2qcow qcow2raw qcow-create
INST_DIR = /usr/sbin
LIBAIO_DIR = ../../libaio/src
+LIBVDISK_DIR = ../../vdisk
+LIBSDIR = lib64
CFLAGS += -Werror
CFLAGS += -Wno-unused
CFLAGS += -fno-strict-aliasing
CFLAGS += -I $(XEN_LIBXC) -I $(LIBAIO_DIR)
-CFLAGS += $(INCLUDES) -I. -I../../xenstore
+CFLAGS += $(INCLUDES) -I. -I../../xenstore -I$(LIBVDISK_DIR)
CFLAGS += -D_GNU_SOURCE
# Get gcc to generate the dependencies for us.
@@ -21,10 +23,10 @@ DEPS = .*.d
THREADLIB := -lpthread -lz
LIBS := -L. -L.. -L../lib
-LIBS += -L$(XEN_LIBXC)
+LIBS += -L$(XEN_LIBXC) -L$(LIBVDISK_DIR) -L$(LIBAIO_DIR)
LIBS += -lblktap -lxenctrl
LIBS += -lcrypto
-LIBS += -lz
+LIBS += -lz -lvdisk -laio
LIBS += -L$(XEN_XENSTORE) -lxenstore
AIOLIBS := $(LIBAIO_DIR)/libaio.a
@@ -34,14 +36,15 @@ BLK-OBJS += block-vmdk.o
BLK-OBJS += block-vmdk.o
BLK-OBJS += block-ram.o
BLK-OBJS += block-qcow.o
+BLK-OBJS += block-vhd.o
BLK-OBJS += aes.o
all: $(IBIN) qcow-util
-blktapctrl: blktapctrl.c
+blktapctrl: blktapctrl.c tapdisk.h
$(CC) $(CFLAGS) -o blktapctrl $(LIBS) blktapctrl.c
-tapdisk: $(BLK-OBJS) tapdisk.c
+tapdisk: $(BLK-OBJS) tapdisk.c tapdisk.h
$(CC) $(CFLAGS) -o tapdisk $(BLK-OBJS) tapdisk.c \
$(AIOLIBS) $(LIBS)
diff -r 92f2f05d6839 tools/blktap/drivers/block-vhd.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap/drivers/block-vhd.c Tue Jun 19 08:12:30 2007 -0400
@@ -0,0 +1,312 @@
+// 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 "tapdisk.h"
+#include <vdisk.h>
+
+
+struct tdvhd_state {
+ vdisk_dev_t *vdisk;
+ int poll_pipe[2]; /* dummy fd for polling on */
+ int fd;
+};
+
+typedef struct td_cbinfo {
+ struct td_state *s;
+ td_callback_t cb;
+ struct vdisk_dev *vdisk;
+ void *private;
+ int id;
+ int cnt;
+} td_cbinfo_t;
+
+static int
+tdvhd_queue_rw(struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
+ int id, void *private, int op)
+{
+ struct tdvhd_state *prv = (struct tdvhd_state *)dd->private;
+ int res = 0;
+ int aio_cnt = prv->vdisk->aio_cnt;
+ td_cbinfo_t *cbi;
+
+ cbi = malloc(sizeof(td_cbinfo_t));
+ if (cbi == NULL) {
+ VIDDBG(0, "Can't allocate callback info\n");
+ return (-ENOMEM);
+ }
+
+ cbi->s = dd->td_state;
+ cbi->cb = cb;
+ cbi->id = id;
+ cbi->vdisk = prv->vdisk;
+ cbi->private = private;
+
+ res = vdisk_rw(prv->vdisk, sector, (uint8_t *)buf,
+ nb_sectors, op, (void *)cbi);
+ if (res == -EBUSY) {
+ blkif_t *blkif = cbi->s->blkif;
+
+ /*
+ * This really should be done in tapdisk.c.
+ * However, we since we don't want to touch it,
+ * we do it here.
+ */
+ blkif->pending_list[id].secs_pending -= nb_sectors;
+
+ free(cbi);
+ }
+
+ // Didn't use async IO
+ if (res > 0) {
+ cbi->cb(dd, 0/*XXX: pass error*/,
+ sector, res>>9,
+ cbi->id, cbi->private);
+ }
+
+ // How many AIOs have been created for this request
+ cbi->cnt = prv->vdisk->aio_cnt - aio_cnt;
+
+ return (res);
+
+}
+
+int tdvhd_queue_read(struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
+ int id, void *private)
+{
+ return (tdvhd_queue_rw(dd, sector, nb_sectors, buf,
+ cb, id, private, VDISK_READ));
+}
+
+int tdvhd_queue_write(struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
+ int id, void *private)
+{
+ return (tdvhd_queue_rw(dd, sector, nb_sectors, buf,
+ cb, id, private, VDISK_WRITE));
+}
+
+int tdvhd_close(struct disk_driver *dd)
+{
+ struct tdvhd_state *prv;
+
+ // We can be called more than once
+ if (dd == NULL)
+ return (0);
+
+ prv = (struct tdvhd_state *)dd->private;
+ if ((prv == NULL) || (prv->vdisk == NULL))
+ return (0); // XXX: Or error?
+
+ vdisk_fini(prv->vdisk);
+
+ free(prv->vdisk);
+ prv->vdisk = NULL;
+
+ close(prv->poll_pipe[0]);
+ close(prv->poll_pipe[1]);
+
+ return 0;
+}
+
+static void tdvhd_get_fd(struct disk_driver *dd)
+{
+ struct tdvhd_state *prv = (struct tdvhd_state *)dd->private;
+ vdisk_dev_t *vdisk = (vdisk_dev_t *)prv->vdisk;
+ int i;
+
+ /*initialise the FD array*/
+ for(i=0;i<MAX_IOFD;i++)
+ dd->io_fd[i] = 0;
+
+ dd->io_fd[0] = vdisk->aio_fd;
+}
+
+/* Open the disk file and initialize aio state. */
+int tdvhd_open (struct disk_driver *dd, const char *filename, td_flag_t flags)
+{
+ int i, fd, ret = 0;
+ struct tdvhd_state *prv = (struct tdvhd_state *)dd->private;
+ int heads, secs, cyls;
+ struct program_props props;
+
+ prv->vdisk = malloc(sizeof(struct vdisk_dev));
+ if (prv->vdisk == NULL) {
+ VIDDBG(0, "Can't allocate memory for vdisk\n");
+ return (-ENOMEM);
+ }
+
+ prv->vdisk->use_aio = 1;
+
+ props.alloc_func = NULL;
+ props.free_func = NULL;
+ props.out_target = VDISK_OUT_SYSLOG;
+ ret = vdisk_init(prv->vdisk, (char *)filename, &props, 0);
+ if (ret) {
+ VIDDBG(0, "Can't initialize vdisk for %s\n", filename);
+ free(prv->vdisk);
+ return (ret>0?(-1*ret):ret);
+ }
+
+ /* set up a pipe so that we can hand back a poll fd that won't fire.*/
+ ret = pipe(prv->poll_pipe);
+ if (ret != 0)
+ return (0 - errno);
+
+ // 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
+ dd->td_state->size = prv->vdisk->sz >> 9;
+ dd->td_state->sector_size = DEFAULT_SECTOR_SIZE;
+
+ tdvhd_get_fd(dd);
+
+done:
+ return ret;
+}
+
+int tdvhd_submit(struct disk_driver *dd)
+{
+ int res;
+ struct tdvhd_state *prv = (struct tdvhd_state *)dd->private;
+ vdisk_dev_t *vdisk = (vdisk_dev_t *)prv->vdisk;
+
+ if (!vdisk->use_aio)
+ return (0);
+
+ if (!vdisk->aio_cnt)
+ return (0);
+
+ VIDDBG(50, "Submitting %d requests\n", vdisk->aio_cnt);
+
+ res = io_submit(vdisk->ioctx, vdisk->aio_cnt, vdisk->aio_submit);
+ if (res != vdisk->aio_cnt)
+ VIDDBG(0, "Can't submit %d AIO requests (submitted %d)\n",
+ vdisk->aio_cnt, res);
+
+ vdisk->aio_cnt = 0;
+
+ return 0;
+}
+
+int tdvhd_do_callbacks(struct disk_driver *dd, int sid)
+{
+ struct tdvhd_state *prv = (struct tdvhd_state *)dd->private;
+ vdisk_dev_t *vdisk = (vdisk_dev_t *)prv->vdisk;
+ int ret, i, rsp = 1, *ptr;
+ struct io_event *ep;
+ td_cbinfo_t *cbi;
+ uint32_t blk;
+
+ /* Non-blocking test for completed io. */
+ ret = io_getevents(vdisk->ioctx, 0, VDISK_HASH_SZ,
+ vdisk->aio_events, NULL);
+
+ for (ep=vdisk->aio_events, i=ret; i>0; i--, ep++) {
+ struct iocb *io = ep->obj;
+ struct pending_aio *pio;
+ int err;
+
+ err = 0;
+
+ pio = (struct pending_aio *)io->data;
+ if (pio == NULL) {
+ VIDDBG(0, "Can't find pending AIO data\n");
+ return (-EIO);
+ }
+
+ if ((signed long)ep->res < 0) {
+ VIDDBG(0, "AIO to block %u for %u blocks reported "
+ "error %ld (%ld)\n", pio->block, pio->num_blocks,
+ ep->res, ep->res2);
+ err = ep->res;
+ } else if (ep->res != io->u.c.nbytes) {
+ /* TODO: handle this case better. */
+ ptr = (int *)&ep->res;
+ VIDDBG(0, "AIO did less than I asked it to "
+ "[%lu,%lu,%d]\n",
+ ep->res, io->u.c.nbytes, *ptr);
+ err = -EIO;
+ }
+
+ cbi = (td_cbinfo_t *)pio->aiocb;
+ if (cbi == NULL) {
+ VIDDBG(0, "callback info is missing\n");
+ //XXX: This is pretty bad. Maybe we should die?
+ continue;
+ }
+ if (cbi->vdisk == NULL) {
+ VIDDBG(0, "Can't find vdisk for pending AIO\n");
+ err = -EIO;
+ } else {
+ int vdisk_err;
+
+ // Let vdisk know that a pending IO has completed
+ pio->res = err;
+ vdisk_err = vdisk_xfer_cb(cbi->vdisk, pio);
+ if (vdisk_err != 0) {
+ VIDDBG(0, "vdisk callback failed\n");
+ //XXX: return (error) ???
+
+ if (err == 0) // Report the earliest error
+ err = vdisk_err;
+ }
+ }
+
+ cbi->cnt--;
+
+ // blktap's callback (usually to kick the driver)
+ rsp += cbi->cb(dd, err,
+ pio->block, /* sector */
+ pio->num_blocks, /* nb_sectors */
+ cbi->id, cbi->private);
+
+ if (cbi->cnt == 0)
+ free(cbi);
+ }
+
+ // XXX: What do we return on errors?
+ return rsp;
+}
+int tdvhd_get_parent_id (struct disk_driver *dd, struct disk_id *id)
+{
+ return TD_NO_PARENT;
+}
+
+int tdvhd_validate_parent (struct disk_driver *dd,
+ struct disk_driver *p, td_flag_t flags)
+{
+ return -EINVAL;
+}
+
+
+
+struct tap_disk tapdisk_vhd = {
+ "tapdisk_vhd",
+ sizeof(struct tdvhd_state),
+ tdvhd_open,
+ tdvhd_queue_read,
+ tdvhd_queue_write,
+ tdvhd_submit,
+ tdvhd_close,
+ tdvhd_do_callbacks,
+ tdvhd_get_parent_id,
+ tdvhd_validate_parent
+};
diff -r 92f2f05d6839 tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c Tue Jun 19 08:00:26 2007 -0400
+++ b/tools/blktap/drivers/tapdisk.c Tue Jun 19 08:00:26 2007 -0400
@@ -556,15 +556,22 @@ int send_responses(struct disk_driver *d
preq = &blkif->pending_list[idx];
req = &preq->req;
- if (res == BLK_NOT_ALLOCATED) {
- res = do_cow_read(dd, req, sidx, sector, nr_secs);
+ if (res == BLK_NOT_ALLOCATED) {
+#if 1
+ /* VHD - do not support */
+ DPRINTF("invalid for VHD's\n");
+ return 0;
+#else
+ /* Original xen code */
+ res = do_cow_read(dd, req, sidx, sector, nr_secs);
if (res >= 0) {
secs_done = res;
res = 0;
} else
secs_done = 0;
- }
-
+#endif
+ }
+
preq->secs_pending -= secs_done;
if (res == -EBUSY && preq->submitting)
diff -r 92f2f05d6839 tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h Tue Jun 19 08:00:26 2007 -0400
+++ b/tools/blktap/drivers/tapdisk.h Tue Jun 19 08:00:26 2007 -0400
@@ -156,6 +156,7 @@ extern struct tap_disk tapdisk_vmdk;
extern struct tap_disk tapdisk_vmdk;
extern struct tap_disk tapdisk_ram;
extern struct tap_disk tapdisk_qcow;
+extern struct tap_disk tapdisk_vhd;
#define MAX_DISK_TYPES 20
@@ -164,6 +165,7 @@ extern struct tap_disk tapdisk_qcow;
#define DISK_TYPE_VMDK 2
#define DISK_TYPE_RAM 3
#define DISK_TYPE_QCOW 4
+#define DISK_TYPE_VHD 5
/*Define Individual Disk Parameters here */
@@ -214,6 +216,16 @@ static disk_info_t qcow_disk = {
0,
#ifdef TAPDISK
&tapdisk_qcow,
+#endif
+};
+
+static disk_info_t vhd_disk = {
+ DISK_TYPE_VHD,
+ "VHD disk (vhd)",
+ "vhd",
+ 1,
+#ifdef TAPDISK
+ &tapdisk_vhd,
#endif
};
@@ -224,6 +236,7 @@ static disk_info_t *dtypes[] = {
&vmdk_disk,
&ram_disk,
&qcow_disk,
+ &vhd_disk,
};
typedef struct driver_list_entry {
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-06-19 13:16 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-19 13:16 [PATCH 2/4] provide vhd support to blktap Ben Guthro
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.