aboutsummaryrefslogtreecommitdiffstats
path: root/tools/blktap2/include
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-05-26 11:52:31 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-05-26 11:52:31 +0100
commitbd5573a6301a6b229d36670a042a760f89b10dfd (patch)
tree3d9a729ca041e1b1999843a1be834cf7316eb021 /tools/blktap2/include
parent6009f4ddb2cdb8555d2d5e030d351893e971b995 (diff)
downloadxen-bd5573a6301a6b229d36670a042a760f89b10dfd.tar.gz
xen-bd5573a6301a6b229d36670a042a760f89b10dfd.tar.bz2
xen-bd5573a6301a6b229d36670a042a760f89b10dfd.zip
blktap2: a completely rewritten blktap implementation
Benefits to blktap2 over the old version of blktap: * Isolation from xenstore - Blktap devices are now created directly on the linux dom0 command line, rather than being spawned in response to XenStore events. This is handy for debugging, makes blktap generally easier to work with, and is a step toward a generic user-level block device implementation that is not Xen-specific. * Improved tapdisk infrastructure: simpler request forwarding, new request scheduler, request merging, more efficient use of AIO. * Improved tapdisk error handling and memory management. No allocations on the block data path, IO retry logic to protect guests transient block device failures. This has been tested and is known to work on weird environments such as NFS soft mounts. * Pause and snapshot of live virtual disks (see xmsnap script). * VHD support. The VHD code in this release has been rigorously tested, and represents a very mature implementation of the VHD image format. * No more duplication of mechanism with blkback. The blktap kernel module has changed dramatically from the original blktap. Blkback is now always used to talk to Xen guests, blktap just presents a Linux gendisk that blkback can export. This is done while preserving the zero-copy data path from domU to physical device. These patches deprecate the old blktap code, which can hopefully be removed from the tree completely at some point in the future. Signed-off-by: Jake Wires <jake.wires@citrix.com> Signed-off-by: Dutch Meyer <dmeyer@cs.ubc.ca>
Diffstat (limited to 'tools/blktap2/include')
-rw-r--r--tools/blktap2/include/Makefile14
-rw-r--r--tools/blktap2/include/atomicio.h33
-rw-r--r--tools/blktap2/include/blktaplib.h249
-rw-r--r--tools/blktap2/include/libvhd-journal.h68
-rw-r--r--tools/blktap2/include/libvhd.h308
-rw-r--r--tools/blktap2/include/list.h93
-rw-r--r--tools/blktap2/include/lvm-util.h71
-rw-r--r--tools/blktap2/include/relative-path.h43
-rw-r--r--tools/blktap2/include/tapdisk-message.h141
-rw-r--r--tools/blktap2/include/vhd-util.h44
-rw-r--r--tools/blktap2/include/vhd.h221
11 files changed, 1285 insertions, 0 deletions
diff --git a/tools/blktap2/include/Makefile b/tools/blktap2/include/Makefile
new file mode 100644
index 0000000000..7267eac53a
--- /dev/null
+++ b/tools/blktap2/include/Makefile
@@ -0,0 +1,14 @@
+XEN_ROOT := ../../../
+include $(XEN_ROOT)/tools/Rules.mk
+
+.PHONY: all
+all:
+
+.PHONY: install
+install:
+ $(INSTALL_DIR) -p $(DESTDIR)$(INCLUDEDIR)
+
+
+.PHONY: clean
+clean:
+ @:
diff --git a/tools/blktap2/include/atomicio.h b/tools/blktap2/include/atomicio.h
new file mode 100644
index 0000000000..7eccf206b3
--- /dev/null
+++ b/tools/blktap2/include/atomicio.h
@@ -0,0 +1,33 @@
+/* $OpenBSD: atomicio.h,v 1.6 2005/05/24 17:32:43 avsm Exp $ */
+
+/*
+ * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Ensure all of data on socket comes through. f==read || f==vwrite
+ */
+size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
+
+#define vwrite (ssize_t (*)(int, void *, size_t))write
diff --git a/tools/blktap2/include/blktaplib.h b/tools/blktap2/include/blktaplib.h
new file mode 100644
index 0000000000..1824afa943
--- /dev/null
+++ b/tools/blktap2/include/blktaplib.h
@@ -0,0 +1,249 @@
+/* blktaplib.h
+ *
+ * Blktap library userspace code.
+ *
+ * Copyright (c) 2007, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BLKTAPLIB_H__
+#define __BLKTAPLIB_H__
+
+#include <syslog.h>
+#include <xenctrl.h>
+#include <xen/io/blkif.h>
+
+#if 1
+#define DPRINTF(_f, _a...) syslog(LOG_INFO, _f, ##_a)
+#else
+#define DPRINTF(_f, _a...) ((void)0)
+#endif
+
+#define EPRINTF(_f, _a...) syslog(LOG_ERR, "tap-err:%s: " _f, __func__, ##_a)
+
+#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, XC_PAGE_SIZE)
+
+/* size of the extra VMA area to map in attached pages. */
+#define BLKTAP_VMA_PAGES BLK_RING_SIZE
+
+/* blktap IOCTLs: These must correspond with the blktap driver ioctls */
+#define BLKTAP_IOCTL_KICK_FE 1
+#define BLKTAP_IOCTL_KICK_BE 2
+#define BLKTAP_IOCTL_SETMODE 3
+#define BLKTAP_IOCTL_SENDPID 4
+#define BLKTAP_IOCTL_NEWINTF 5
+#define BLKTAP_IOCTL_MINOR 6
+#define BLKTAP_IOCTL_MAJOR 7
+#define BLKTAP_QUERY_ALLOC_REQS 8
+#define BLKTAP_IOCTL_FREEINTF 9
+#define BLKTAP_IOCTL_PRINT_IDXS 100
+#define BLKTAP_IOCTL_BACKDEV_SETUP 200
+
+#define PRIO_SPECIAL_IO -9999
+
+/* blktap switching modes: (Set with BLKTAP_IOCTL_SETMODE) */
+#define BLKTAP_MODE_PASSTHROUGH 0x00000000 /* default */
+#define BLKTAP_MODE_INTERCEPT_FE 0x00000001
+#define BLKTAP_MODE_INTERCEPT_BE 0x00000002
+
+#define BLKTAP_MODE_INTERPOSE \
+ (BLKTAP_MODE_INTERCEPT_FE | BLKTAP_MODE_INTERCEPT_BE)
+
+static inline int BLKTAP_MODE_VALID(unsigned long arg)
+{
+ return (
+ ( arg == BLKTAP_MODE_PASSTHROUGH ) ||
+ ( arg == BLKTAP_MODE_INTERCEPT_FE ) ||
+ ( arg == BLKTAP_MODE_INTERPOSE ) );
+}
+
+#define MAX_REQUESTS BLK_RING_SIZE
+
+#define BLKTAP_IOCTL_KICK 1
+#define MAX_PENDING_REQS BLK_RING_SIZE
+#define BLKTAP_DEV_DIR "/dev/xen"
+#define BLKTAP_DEV_NAME "blktap"
+#define BACKDEV_NAME "backdev"
+#define BLKTAP_DEV_MINOR 0
+#define BLKTAP_CTRL_DIR "/var/run/tap"
+
+extern int blktap_major;
+
+#define BLKTAP_RING_PAGES 1 /* Front */
+#define BLKTAP_MMAP_REGION_SIZE (BLKTAP_RING_PAGES + MMAP_PAGES)
+
+struct blkif;
+struct blkif_info;
+
+typedef struct {
+ blkif_request_t req;
+ int submitting;
+ int secs_pending;
+ int16_t status;
+ int num_retries;
+ struct timeval last_try;
+} pending_req_t;
+
+typedef struct blkif {
+ domid_t domid;
+ long int handle;
+
+ long int pdev;
+ long int readonly;
+
+ enum { DISCONNECTED, DISCONNECTING, CONNECTED } state;
+
+ struct blkif_ops *ops;
+ struct blkif *hash_next;
+
+ void *prv; /* device-specific data */
+ struct blkif_info *info; /*Image parameter passing */
+ pending_req_t pending_list[MAX_REQUESTS];
+ int devnum;
+ int fds[2];
+ int be_id;
+ char *backend_path;
+ int major;
+ int minor;
+ pid_t tappid;
+ int drivertype;
+ uint16_t cookie;
+ int err;
+} blkif_t;
+
+typedef struct blkif_info {
+ char *params;
+ int readonly;
+ int storage;
+} blkif_info_t;
+
+typedef struct tapdev_info {
+ int fd;
+ char *mem;
+ blkif_sring_t *sring;
+ blkif_back_ring_t fe_ring;
+ unsigned long vstart;
+ blkif_t *blkif;
+} tapdev_info_t;
+
+typedef struct domid_translate {
+ unsigned short domid;
+ unsigned short busid;
+} domid_translate_t ;
+
+typedef struct image {
+ unsigned long long size;
+ unsigned long secsize;
+ unsigned int info;
+} image_t;
+
+typedef struct msg_hdr {
+ uint16_t type;
+ uint16_t len;
+ uint16_t drivertype;
+ uint16_t cookie;
+} msg_hdr_t;
+
+typedef struct msg_params {
+ uint8_t readonly;
+ int path_off;
+ int path_len;
+ int storage;
+} msg_params_t;
+
+typedef struct msg_newdev {
+ uint8_t devnum;
+ uint16_t domid;
+} msg_newdev_t;
+
+typedef struct msg_pid {
+ pid_t pid;
+} msg_pid_t;
+
+typedef struct msg_cp {
+ int cp_uuid_off;
+ int cp_uuid_len;
+ int cp_drivertype;
+} msg_cp_t;
+
+typedef struct msg_lock {
+ int ro;
+ int enforce;
+ int uuid_off;
+ int uuid_len;
+} msg_lock_t;
+
+#define READ 0
+#define WRITE 1
+
+/*Control Messages between manager and tapdev*/
+#define CTLMSG_PARAMS 1
+#define CTLMSG_IMG 2
+#define CTLMSG_IMG_FAIL 3
+#define CTLMSG_NEWDEV 4
+#define CTLMSG_NEWDEV_RSP 5
+#define CTLMSG_NEWDEV_FAIL 6
+#define CTLMSG_CLOSE 7
+#define CTLMSG_CLOSE_RSP 8
+#define CTLMSG_PID 9
+#define CTLMSG_PID_RSP 10
+#define CTLMSG_CHECKPOINT 11
+#define CTLMSG_CHECKPOINT_RSP 12
+#define CTLMSG_LOCK 13
+#define CTLMSG_LOCK_RSP 14
+#define CTLMSG_PAUSE 15
+#define CTLMSG_PAUSE_RSP 16
+#define CTLMSG_RESUME 17
+#define CTLMSG_RESUME_RSP 18
+
+#define TAPDISK_STORAGE_TYPE_NFS 1
+#define TAPDISK_STORAGE_TYPE_EXT 2
+#define TAPDISK_STORAGE_TYPE_LVM 3
+#define TAPDISK_STORAGE_TYPE_DEFAULT TAPDISK_STORAGE_TYPE_EXT
+
+/* Abitrary values, must match the underlying driver... */
+#define MAX_TAP_DEV 256
+
+/* Accessing attached data page mappings */
+#define MMAP_PAGES \
+ (MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST)
+#define MMAP_VADDR(_vstart,_req,_seg) \
+ ((_vstart) + \
+ ((_req) * BLKIF_MAX_SEGMENTS_PER_REQUEST * getpagesize()) + \
+ ((_seg) * getpagesize()))
+
+/* Defines that are only used by library clients */
+
+#ifndef __COMPILING_BLKTAP_LIB
+
+static char *blkif_op_name[] = {
+ [BLKIF_OP_READ] = "READ",
+ [BLKIF_OP_WRITE] = "WRITE",
+};
+
+#endif /* __COMPILING_BLKTAP_LIB */
+
+#endif /* __BLKTAPLIB_H__ */
diff --git a/tools/blktap2/include/libvhd-journal.h b/tools/blktap2/include/libvhd-journal.h
new file mode 100644
index 0000000000..2f32ff02ca
--- /dev/null
+++ b/tools/blktap2/include/libvhd-journal.h
@@ -0,0 +1,68 @@
+/* Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _VHD_JOURNAL_H_
+#define _VHD_JOURNAL_H_
+
+#include <inttypes.h>
+
+#include "libvhd.h"
+
+#define VHD_JOURNAL_METADATA 0x01
+#define VHD_JOURNAL_DATA 0x02
+
+#define VHD_JOURNAL_HEADER_COOKIE "vjournal"
+#define VHD_JOURNAL_ENTRY_COOKIE 0xaaaa12344321aaaa
+
+typedef struct vhd_journal_header {
+ char cookie[8];
+ uuid_t uuid;
+ uint64_t vhd_footer_offset;
+ uint32_t journal_data_entries;
+ uint32_t journal_metadata_entries;
+ uint64_t journal_data_offset;
+ uint64_t journal_metadata_offset;
+ uint64_t journal_eof;
+ char pad[448];
+} vhd_journal_header_t;
+
+typedef struct vhd_journal {
+ char *jname;
+ int jfd;
+ int is_block; /* is jfd a block device */
+ vhd_journal_header_t header;
+ vhd_context_t vhd;
+} vhd_journal_t;
+
+int vhd_journal_create(vhd_journal_t *, const char *file, const char *jfile);
+int vhd_journal_open(vhd_journal_t *, const char *file, const char *jfile);
+int vhd_journal_add_block(vhd_journal_t *, uint32_t block, char mode);
+int vhd_journal_commit(vhd_journal_t *);
+int vhd_journal_revert(vhd_journal_t *);
+int vhd_journal_close(vhd_journal_t *);
+int vhd_journal_remove(vhd_journal_t *);
+
+#endif
diff --git a/tools/blktap2/include/libvhd.h b/tools/blktap2/include/libvhd.h
new file mode 100644
index 0000000000..b128ebaf38
--- /dev/null
+++ b/tools/blktap2/include/libvhd.h
@@ -0,0 +1,308 @@
+/* Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _VHD_LIB_H_
+#define _VHD_LIB_H_
+
+#include <string.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <uuid/uuid.h>
+
+#include "vhd.h"
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ #define BE16_IN(foo) (*(foo)) = bswap_16(*(foo))
+ #define BE32_IN(foo) (*(foo)) = bswap_32(*(foo))
+ #define BE64_IN(foo) (*(foo)) = bswap_64(*(foo))
+ #define BE16_OUT(foo) (*(foo)) = bswap_16(*(foo))
+ #define BE32_OUT(foo) (*(foo)) = bswap_32(*(foo))
+ #define BE64_OUT(foo) (*(foo)) = bswap_64(*(foo))
+#else
+ #define BE16_IN(foo)
+ #define BE32_IN(foo)
+ #define BE64_IN(foo)
+ #define BE32_OUT(foo)
+ #define BE32_OUT(foo)
+ #define BE64_OUT(foo)
+#endif
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#define VHD_MAX_NAME_LEN 1024
+
+#define VHD_BLOCK_SHIFT 21
+#define VHD_BLOCK_SIZE (1ULL << VHD_BLOCK_SHIFT)
+
+#define UTF_16 "UTF-16"
+#define UTF_16LE "UTF-16LE"
+#define UTF_16BE "UTF-16BE"
+
+#define VHD_OPEN_RDONLY 0x00001
+#define VHD_OPEN_RDWR 0x00002
+#define VHD_OPEN_FAST 0x00004
+#define VHD_OPEN_STRICT 0x00008
+#define VHD_OPEN_IGNORE_DISABLED 0x00010
+
+#define VHD_FLAG_CREAT_PARENT_RAW 0x00001
+
+#define vhd_flag_set(word, flag) ((word) |= (flag))
+#define vhd_flag_clear(word, flag) ((word) &= ~(flag))
+#define vhd_flag_test(word, flag) ((word) & (flag))
+
+
+#define ENABLE_FAILURE_TESTING
+#define FAIL_REPARENT_BEGIN 0
+#define FAIL_REPARENT_LOCATOR 1
+#define FAIL_REPARENT_END 2
+#define FAIL_RESIZE_BEGIN 3
+#define FAIL_RESIZE_DATA_MOVED 4
+#define FAIL_RESIZE_METADATA_MOVED 5
+#define FAIL_RESIZE_END 6
+#define NUM_FAIL_TESTS 7
+
+#ifdef ENABLE_FAILURE_TESTING
+#define TEST_FAIL_AT(point) \
+ if (TEST_FAIL[point]) { \
+ printf("Failing at %s\n", ENV_VAR_FAIL[point]); exit(EINVAL); }
+#define TEST_FAIL_EXTERN_VARS \
+ extern const char* ENV_VAR_FAIL[]; \
+ extern int TEST_FAIL[];
+#else
+#define TEST_FAIL_AT(point)
+#define TEST_FAIL_EXTERN_VARS
+#endif // ENABLE_FAILURE_TESTING
+
+
+static const char VHD_POISON_COOKIE[] = "v_poison";
+
+typedef struct hd_ftr vhd_footer_t;
+typedef struct dd_hdr vhd_header_t;
+typedef struct vhd_bat vhd_bat_t;
+typedef struct vhd_batmap vhd_batmap_t;
+typedef struct dd_batmap_hdr vhd_batmap_header_t;
+typedef struct prt_loc vhd_parent_locator_t;
+typedef struct vhd_context vhd_context_t;
+typedef uint32_t vhd_flag_creat_t;
+
+struct vhd_bat {
+ uint32_t spb;
+ uint32_t entries;
+ uint32_t *bat;
+};
+
+struct vhd_batmap {
+ vhd_batmap_header_t header;
+ char *map;
+};
+
+struct vhd_context {
+ int fd;
+ char *file;
+ int oflags;
+ int is_block;
+
+ uint32_t spb;
+ uint32_t bm_secs;
+
+ vhd_header_t header;
+ vhd_footer_t footer;
+ vhd_bat_t bat;
+ vhd_batmap_t batmap;
+};
+
+static inline uint32_t
+secs_round_up(uint64_t bytes)
+{
+ return ((bytes + (VHD_SECTOR_SIZE - 1)) >> VHD_SECTOR_SHIFT);
+}
+
+static inline uint32_t
+secs_round_up_no_zero(uint64_t bytes)
+{
+ return (secs_round_up(bytes) ? : 1);
+}
+
+static inline uint64_t
+vhd_sectors_to_bytes(uint64_t sectors)
+{
+ return sectors << VHD_SECTOR_SHIFT;
+}
+
+static inline uint64_t
+vhd_bytes_padded(uint64_t bytes)
+{
+ return vhd_sectors_to_bytes(secs_round_up_no_zero(bytes));
+}
+
+static inline int
+vhd_type_dynamic(vhd_context_t *ctx)
+{
+ return (ctx->footer.type == HD_TYPE_DYNAMIC ||
+ ctx->footer.type == HD_TYPE_DIFF);
+}
+
+static inline int
+vhd_creator_tapdisk(vhd_context_t *ctx)
+{
+ return !strncmp(ctx->footer.crtr_app, "tap", 3);
+}
+
+static inline int
+vhd_disabled(vhd_context_t *ctx)
+{
+ return (!memcmp(ctx->footer.cookie,
+ VHD_POISON_COOKIE, sizeof(ctx->footer.cookie)));
+}
+
+static inline size_t
+vhd_parent_locator_size(vhd_parent_locator_t *loc)
+{
+ /*
+ * MICROSOFT_COMPAT
+ * data_space *should* be in sectors,
+ * but sometimes we find it in bytes
+ */
+ if (loc->data_space < 512)
+ return vhd_sectors_to_bytes(loc->data_space);
+ else if (loc->data_space % 512 == 0)
+ return loc->data_space;
+ else
+ return 0;
+}
+
+static inline int
+vhd_parent_raw(vhd_context_t *ctx)
+{
+ return uuid_is_null(ctx->header.prt_uuid);
+}
+
+void libvhd_set_log_level(int);
+
+int vhd_test_file_fixed(const char *, int *);
+
+uint32_t vhd_time(time_t time);
+size_t vhd_time_to_string(uint32_t timestamp, char *target);
+uint32_t vhd_chs(uint64_t size);
+
+uint32_t vhd_checksum_footer(vhd_footer_t *);
+uint32_t vhd_checksum_header(vhd_header_t *);
+uint32_t vhd_checksum_batmap(vhd_batmap_t *);
+
+void vhd_footer_in(vhd_footer_t *);
+void vhd_footer_out(vhd_footer_t *);
+void vhd_header_in(vhd_header_t *);
+void vhd_header_out(vhd_header_t *);
+void vhd_bat_in(vhd_bat_t *);
+void vhd_bat_out(vhd_bat_t *);
+void vhd_batmap_header_in(vhd_batmap_t *);
+void vhd_batmap_header_out(vhd_batmap_t *);
+
+int vhd_validate_footer(vhd_footer_t *footer);
+int vhd_validate_header(vhd_header_t *header);
+int vhd_validate_batmap_header(vhd_batmap_t *batmap);
+int vhd_validate_batmap(vhd_batmap_t *batmap);
+int vhd_validate_platform_code(uint32_t code);
+
+int vhd_open(vhd_context_t *, const char *file, int flags);
+void vhd_close(vhd_context_t *);
+int vhd_create(const char *name, uint64_t bytes, int type, vhd_flag_creat_t);
+/* vhd_snapshot: the bytes parameter is optional and can be 0 if the snapshot
+ * is to have the same size as the (first non-empty) parent */
+int vhd_snapshot(const char *snapshot, uint64_t bytes, const char *parent,
+ vhd_flag_creat_t);
+
+int vhd_hidden(vhd_context_t *, int *);
+int vhd_chain_depth(vhd_context_t *, int *);
+
+off64_t vhd_position(vhd_context_t *);
+int vhd_seek(vhd_context_t *, off64_t, int);
+int vhd_read(vhd_context_t *, void *, size_t);
+int vhd_write(vhd_context_t *, void *, size_t);
+
+int vhd_offset(vhd_context_t *, uint32_t, uint32_t *);
+
+int vhd_end_of_headers(vhd_context_t *ctx, off64_t *off);
+int vhd_end_of_data(vhd_context_t *ctx, off64_t *off);
+int vhd_batmap_header_offset(vhd_context_t *ctx, off64_t *off);
+
+int vhd_get_header(vhd_context_t *);
+int vhd_get_footer(vhd_context_t *);
+int vhd_get_bat(vhd_context_t *);
+int vhd_get_batmap(vhd_context_t *);
+
+void vhd_put_header(vhd_context_t *);
+void vhd_put_footer(vhd_context_t *);
+void vhd_put_bat(vhd_context_t *);
+void vhd_put_batmap(vhd_context_t *);
+
+int vhd_has_batmap(vhd_context_t *);
+int vhd_batmap_test(vhd_context_t *, vhd_batmap_t *, uint32_t);
+void vhd_batmap_set(vhd_context_t *, vhd_batmap_t *, uint32_t);
+void vhd_batmap_clear(vhd_context_t *, vhd_batmap_t *, uint32_t);
+
+int vhd_get_phys_size(vhd_context_t *, off64_t *);
+int vhd_set_phys_size(vhd_context_t *, off64_t);
+
+int vhd_bitmap_test(vhd_context_t *, char *, uint32_t);
+void vhd_bitmap_set(vhd_context_t *, char *, uint32_t);
+void vhd_bitmap_clear(vhd_context_t *, char *, uint32_t);
+
+int vhd_parent_locator_count(vhd_context_t *);
+int vhd_parent_locator_get(vhd_context_t *, char **);
+int vhd_parent_locator_read(vhd_context_t *, vhd_parent_locator_t *, char **);
+int vhd_find_parent(vhd_context_t *, const char *, char **);
+int vhd_parent_locator_write_at(vhd_context_t *, const char *,
+ off64_t, uint32_t, size_t,
+ vhd_parent_locator_t *);
+
+int vhd_header_decode_parent(vhd_context_t *, vhd_header_t *, char **);
+int vhd_change_parent(vhd_context_t *, char *parent_path, int raw);
+
+int vhd_read_footer(vhd_context_t *, vhd_footer_t *);
+int vhd_read_footer_at(vhd_context_t *, vhd_footer_t *, off64_t);
+int vhd_read_footer_strict(vhd_context_t *, vhd_footer_t *);
+int vhd_read_header(vhd_context_t *, vhd_header_t *);
+int vhd_read_header_at(vhd_context_t *, vhd_header_t *, off64_t);
+int vhd_read_bat(vhd_context_t *, vhd_bat_t *);
+int vhd_read_batmap(vhd_context_t *, vhd_batmap_t *);
+int vhd_read_bitmap(vhd_context_t *, uint32_t block, char **bufp);
+int vhd_read_block(vhd_context_t *, uint32_t block, char **bufp);
+
+int vhd_write_footer(vhd_context_t *, vhd_footer_t *);
+int vhd_write_footer_at(vhd_context_t *, vhd_footer_t *, off64_t);
+int vhd_write_header(vhd_context_t *, vhd_header_t *);
+int vhd_write_header_at(vhd_context_t *, vhd_header_t *, off64_t);
+int vhd_write_bat(vhd_context_t *, vhd_bat_t *);
+int vhd_write_batmap(vhd_context_t *, vhd_batmap_t *);
+int vhd_write_bitmap(vhd_context_t *, uint32_t block, char *bitmap);
+int vhd_write_block(vhd_context_t *, uint32_t block, char *data);
+
+int vhd_io_read(vhd_context_t *, char *, uint64_t, uint32_t);
+int vhd_io_write(vhd_context_t *, char *, uint64_t, uint32_t);
+
+#endif
diff --git a/tools/blktap2/include/list.h b/tools/blktap2/include/list.h
new file mode 100644
index 0000000000..03a524be01
--- /dev/null
+++ b/tools/blktap2/include/list.h
@@ -0,0 +1,93 @@
+/*
+ * list.h
+ *
+ * This is a subset of linux's list.h intended to be used in user-space.
+ *
+ */
+
+#ifndef __LIST_H__
+#define __LIST_H__
+
+#define LIST_POISON1 ((void *) 0x00100100)
+#define LIST_POISON2 ((void *) 0x00200200)
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+ list->next = list;
+ list->prev = list;
+}
+
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
+}
+
+static inline void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+static inline int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+static inline int list_is_last(const struct list_head *list,
+ const struct list_head *head)
+{
+ return list->next == head;
+}
+
+#define list_entry(ptr, type, member) \
+ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+#endif /* __LIST_H__ */
diff --git a/tools/blktap2/include/lvm-util.h b/tools/blktap2/include/lvm-util.h
new file mode 100644
index 0000000000..95f3320334
--- /dev/null
+++ b/tools/blktap2/include/lvm-util.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _LVM_UTIL_H_
+#define _LVM_UTIL_H_
+
+#include <inttypes.h>
+
+#define MAX_NAME_SIZE 256
+
+#define LVM_SEG_TYPE_LINEAR 1
+#define LVM_SEG_TYPE_UNKNOWN 2
+
+struct lv_segment {
+ uint8_t type;
+ char device[MAX_NAME_SIZE];
+ uint64_t pe_start;
+ uint64_t pe_size;
+};
+
+struct lv {
+ char name[MAX_NAME_SIZE];
+ uint64_t size;
+ uint32_t segments;
+ struct lv_segment first_segment;
+};
+
+struct pv {
+ char name[MAX_NAME_SIZE];
+ uint64_t start;
+};
+
+struct vg {
+ char name[MAX_NAME_SIZE];
+ uint64_t extent_size;
+
+ int pv_cnt;
+ struct pv *pvs;
+
+ int lv_cnt;
+ struct lv *lvs;
+};
+
+int lvm_scan_vg(const char *vg_name, struct vg *vg);
+void lvm_free_vg(struct vg *vg);
+
+#endif
diff --git a/tools/blktap2/include/relative-path.h b/tools/blktap2/include/relative-path.h
new file mode 100644
index 0000000000..d78f94d023
--- /dev/null
+++ b/tools/blktap2/include/relative-path.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _RELATIVE_PATH_H_
+#define _RELATIVE_PATH_H_
+
+#include <syslog.h>
+
+#define DELIMITER '/'
+#define MAX_NAME_LEN 1000
+
+#define EPRINTF(_f, _a...) syslog(LOG_ERR, "tap-err:%s: " _f, __func__, ##_a)
+
+/*
+ * returns a relative path from @src to @dest
+ * result should be freed
+ */
+char *relative_path_to(char *src, char *dest, int *err);
+
+#endif
diff --git a/tools/blktap2/include/tapdisk-message.h b/tools/blktap2/include/tapdisk-message.h
new file mode 100644
index 0000000000..1a86dcb6a3
--- /dev/null
+++ b/tools/blktap2/include/tapdisk-message.h
@@ -0,0 +1,141 @@
+/* Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _TAPDISK_MESSAGE_H_
+#define _TAPDISK_MESSAGE_H_
+
+#include <inttypes.h>
+
+#define TAPDISK_MESSAGE_MAX_PATH_LENGTH 256
+#define TAPDISK_MESSAGE_STRING_LENGTH 256
+
+#define TAPDISK_MESSAGE_FLAG_SHARED 0x01
+#define TAPDISK_MESSAGE_FLAG_RDONLY 0x02
+#define TAPDISK_MESSAGE_FLAG_ADD_CACHE 0x04
+#define TAPDISK_MESSAGE_FLAG_VHD_INDEX 0x08
+#define TAPDISK_MESSAGE_FLAG_LOG_DIRTY 0x10
+
+typedef struct tapdisk_message tapdisk_message_t;
+typedef uint8_t tapdisk_message_flag_t;
+typedef struct tapdisk_message_image tapdisk_message_image_t;
+typedef struct tapdisk_message_params tapdisk_message_params_t;
+typedef struct tapdisk_message_string tapdisk_message_string_t;
+
+struct tapdisk_message_params {
+ tapdisk_message_flag_t flags;
+
+ uint8_t storage;
+ uint32_t devnum;
+ uint32_t domid;
+ uint16_t path_len;
+ char path[TAPDISK_MESSAGE_MAX_PATH_LENGTH];
+};
+
+struct tapdisk_message_image {
+ uint64_t sectors;
+ uint32_t sector_size;
+ uint32_t info;
+};
+
+struct tapdisk_message_string {
+ char text[TAPDISK_MESSAGE_STRING_LENGTH];
+};
+
+struct tapdisk_message {
+ uint16_t type;
+ uint16_t cookie;
+ uint16_t drivertype;
+
+ union {
+ pid_t tapdisk_pid;
+ tapdisk_message_image_t image;
+ tapdisk_message_params_t params;
+ tapdisk_message_string_t string;
+ } u;
+};
+
+enum tapdisk_message_id {
+ TAPDISK_MESSAGE_ERROR = 1,
+ TAPDISK_MESSAGE_RUNTIME_ERROR,
+ TAPDISK_MESSAGE_PID,
+ TAPDISK_MESSAGE_PID_RSP,
+ TAPDISK_MESSAGE_OPEN,
+ TAPDISK_MESSAGE_OPEN_RSP,
+ TAPDISK_MESSAGE_PAUSE,
+ TAPDISK_MESSAGE_PAUSE_RSP,
+ TAPDISK_MESSAGE_RESUME,
+ TAPDISK_MESSAGE_RESUME_RSP,
+ TAPDISK_MESSAGE_CLOSE,
+ TAPDISK_MESSAGE_CLOSE_RSP,
+ TAPDISK_MESSAGE_EXIT,
+};
+
+static inline char *
+tapdisk_message_name(enum tapdisk_message_id id)
+{
+ switch (id) {
+ case TAPDISK_MESSAGE_ERROR:
+ return "error";
+
+ case TAPDISK_MESSAGE_PID:
+ return "pid";
+
+ case TAPDISK_MESSAGE_PID_RSP:
+ return "pid response";
+
+ case TAPDISK_MESSAGE_OPEN:
+ return "open";
+
+ case TAPDISK_MESSAGE_OPEN_RSP:
+ return "open response";
+
+ case TAPDISK_MESSAGE_PAUSE:
+ return "pause";
+
+ case TAPDISK_MESSAGE_PAUSE_RSP:
+ return "pause response";
+
+ case TAPDISK_MESSAGE_RESUME:
+ return "resume";
+
+ case TAPDISK_MESSAGE_RESUME_RSP:
+ return "resume response";
+
+ case TAPDISK_MESSAGE_CLOSE:
+ return "close";
+
+ case TAPDISK_MESSAGE_CLOSE_RSP:
+ return "close response";
+
+ case TAPDISK_MESSAGE_EXIT:
+ return "exit";
+
+ default:
+ return "unknown";
+ }
+}
+
+#endif
diff --git a/tools/blktap2/include/vhd-util.h b/tools/blktap2/include/vhd-util.h
new file mode 100644
index 0000000000..11f077e2bf
--- /dev/null
+++ b/tools/blktap2/include/vhd-util.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _VHD_UTIL_H_
+#define _VHD_UTIL_H_
+
+int vhd_util_create(int argc, char **argv);
+int vhd_util_snapshot(int argc, char **argv);
+int vhd_util_query(int argc, char **argv);
+int vhd_util_read(int argc, char **argv);
+int vhd_util_set_field(int argc, char **argv);
+int vhd_util_repair(int argc, char **argv);
+int vhd_util_fill(int argc, char **argv);
+int vhd_util_resize(int argc, char **argv);
+int vhd_util_coalesce(int argc, char **argv);
+int vhd_util_modify(int argc, char **argv);
+int vhd_util_scan(int argc, char **argv);
+int vhd_util_check(int argc, char **argv);
+int vhd_util_revert(int argc, char **argv);
+
+#endif
diff --git a/tools/blktap2/include/vhd.h b/tools/blktap2/include/vhd.h
new file mode 100644
index 0000000000..4da5f86668
--- /dev/null
+++ b/tools/blktap2/include/vhd.h
@@ -0,0 +1,221 @@
+/* Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef __VHD_H__
+#define __VHD_H__
+
+#include <asm/types.h>
+#include <uuid/uuid.h>
+#include <inttypes.h>
+
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+#define DEBUG 1
+
+/* ---------------------------------------------------------------------- */
+/* General definitions. */
+/* ---------------------------------------------------------------------- */
+
+#define VHD_SECTOR_SIZE 512
+#define VHD_SECTOR_SHIFT 9
+
+/* ---------------------------------------------------------------------- */
+/* This is the generic disk footer, used by all disks. */
+/* ---------------------------------------------------------------------- */
+
+struct hd_ftr {
+ char cookie[8]; /* Identifies original creator of the disk */
+ u32 features; /* Feature Support -- see below */
+ u32 ff_version; /* (major,minor) version of disk file */
+ u64 data_offset; /* Abs. offset from SOF to next structure */
+ u32 timestamp; /* Creation time. secs since 1/1/2000GMT */
+ char crtr_app[4]; /* Creator application */
+ u32 crtr_ver; /* Creator version (major,minor) */
+ u32 crtr_os; /* Creator host OS */
+ u64 orig_size; /* Size at creation (bytes) */
+ u64 curr_size; /* Current size of disk (bytes) */
+ u32 geometry; /* Disk geometry */
+ u32 type; /* Disk type */
+ u32 checksum; /* 1's comp sum of this struct. */
+ uuid_t uuid; /* Unique disk ID, used for naming parents */
+ char saved; /* one-bit -- is this disk/VM in a saved state? */
+ char hidden; /* tapdisk-specific field: is this vdi hidden? */
+ char reserved[426]; /* padding */
+};
+
+/* VHD cookie string. */
+static const char HD_COOKIE[9] = "conectix";
+
+/* Feature fields in hd_ftr */
+#define HD_NO_FEATURES 0x00000000
+#define HD_TEMPORARY 0x00000001 /* disk can be deleted on shutdown */
+#define HD_RESERVED 0x00000002 /* NOTE: must always be set */
+
+/* Version field in hd_ftr */
+#define HD_FF_VERSION 0x00010000
+
+/* Known creator OS type fields in hd_ftr.crtr_os */
+#define HD_CR_OS_WINDOWS 0x5769326B /* (Wi2k) */
+#define HD_CR_OS_MACINTOSH 0x4D616320 /* (Mac ) */
+
+/*
+ * version 0.1: little endian bitmaps
+ * version 1.1: big endian bitmaps; batmap
+ * version 1.2: libvhd
+ * version 1.3: batmap version bump to 1.2
+ */
+#define VHD_VERSION(major, minor) (((major) << 16) | ((minor) & 0x0000FFFF))
+#define VHD_CURRENT_VERSION VHD_VERSION(1, 3)
+
+/* Disk geometry accessor macros. */
+/* Geometry is a triple of (cylinders (2 bytes), tracks (1 byte), and
+ * secotrs-per-track (1 byte))
+ */
+#define GEOM_GET_CYLS(_g) (((_g) >> 16) & 0xffff)
+#define GEOM_GET_HEADS(_g) (((_g) >> 8) & 0xff)
+#define GEOM_GET_SPT(_g) ((_g) & 0xff)
+
+#define GEOM_ENCODE(_c, _h, _s) (((_c) << 16) | ((_h) << 8) | (_s))
+
+/* type field in hd_ftr */
+#define HD_TYPE_NONE 0
+#define HD_TYPE_FIXED 2 /* fixed-allocation disk */
+#define HD_TYPE_DYNAMIC 3 /* dynamic disk */
+#define HD_TYPE_DIFF 4 /* differencing disk */
+
+/* String table for hd.type */
+static const char *HD_TYPE_STR[7] = {
+ "None", /* 0 */
+ "Reserved (deprecated)", /* 1 */
+ "Fixed hard disk", /* 2 */
+ "Dynamic hard disk", /* 3 */
+ "Differencing hard disk", /* 4 */
+ "Reserved (deprecated)", /* 5 */
+ "Reserved (deprecated)" /* 6 */
+};
+
+#define HD_TYPE_MAX 6
+
+struct prt_loc {
+ u32 code; /* Platform code -- see defines below. */
+ u32 data_space; /* Number of 512-byte sectors to store locator */
+ u32 data_len; /* Actual length of parent locator in bytes */
+ u32 res; /* Must be zero */
+ u64 data_offset; /* Absolute offset of locator data (bytes) */
+};
+
+/* Platform Codes */
+#define PLAT_CODE_NONE 0x0
+#define PLAT_CODE_WI2R 0x57693272 /* deprecated */
+#define PLAT_CODE_WI2K 0x5769326B /* deprecated */
+#define PLAT_CODE_W2RU 0x57327275 /* Windows relative path (UTF-16) */
+#define PLAT_CODE_W2KU 0x57326B75 /* Windows absolute path (UTF-16) */
+#define PLAT_CODE_MAC 0x4D616320 /* MacOS alias stored as a blob. */
+#define PLAT_CODE_MACX 0x4D616358 /* File URL (UTF-8), see RFC 2396. */
+
+/* ---------------------------------------------------------------------- */
+/* This is the dynamic disk header. */
+/* ---------------------------------------------------------------------- */
+
+struct dd_hdr {
+ char cookie[8]; /* Should contain "cxsparse" */
+ u64 data_offset; /* Byte offset of next record. (Unused) 0xffs */
+ u64 table_offset; /* Absolute offset to the BAT. */
+ u32 hdr_ver; /* Version of the dd_hdr (major,minor) */
+ u32 max_bat_size; /* Maximum number of entries in the BAT */
+ u32 block_size; /* Block size in bytes. Must be power of 2. */
+ u32 checksum; /* Header checksum. 1's comp of all fields. */
+ uuid_t prt_uuid; /* ID of the parent disk. */
+ u32 prt_ts; /* Modification time of the parent disk */
+ u32 res1; /* Reserved. */
+ char prt_name[512]; /* Parent unicode name. */
+ struct prt_loc loc[8]; /* Parent locator entries. */
+ char res2[256]; /* Reserved. */
+};
+
+/* VHD cookie string. */
+static const char DD_COOKIE[9] = "cxsparse";
+
+/* Version field in hd_ftr */
+#define DD_VERSION 0x00010000
+
+/* Default blocksize is 2 meg. */
+#define DD_BLOCKSIZE_DEFAULT 0x00200000
+
+#define DD_BLK_UNUSED 0xFFFFFFFF
+
+struct dd_batmap_hdr {
+ char cookie[8]; /* should contain "tdbatmap" */
+ u64 batmap_offset; /* byte offset to batmap */
+ u32 batmap_size; /* batmap size in sectors */
+ u32 batmap_version; /* version of batmap */
+ u32 checksum; /* batmap checksum -- 1's complement of batmap */
+};
+
+static const char VHD_BATMAP_COOKIE[9] = "tdbatmap";
+
+/*
+ * version 1.1: signed char checksum
+ */
+#define VHD_BATMAP_VERSION(major, minor) (((major) << 16) | ((minor) & 0x0000FFFF))
+#define VHD_BATMAP_CURRENT_VERSION VHD_BATMAP_VERSION(1, 2)
+
+/* Layout of a dynamic disk:
+ *
+ * +-------------------------------------------------+
+ * | Mirror image of HD footer (hd_ftr) (512 bytes) |
+ * +-------------------------------------------------+
+ * | Sparse drive header (dd_hdr) (1024 bytes) |
+ * +-------------------------------------------------+
+ * | BAT (Block allocation table) |
+ * | - Array of absolute sector offsets into the |
+ * | file (u32). |
+ * | - Rounded up to a sector boundary. |
+ * | - Unused entries are marked as 0xFFFFFFFF |
+ * | - max entries in dd_hdr->max_bat_size |
+ * +-------------------------------------------------+
+ * | Data Block 0 |
+ * | Bitmap (padded to 512 byte sector boundary) |
+ * | - each bit indicates whether the associated |
+ * | sector within this block is used. |
+ * | Data |
+ * | - power-of-two multiple of sectors. |
+ * | - default 2MB (4096 * 512) |
+ * | - Any entries with zero in bitmap should be |
+ * | zero on disk |
+ * +-------------------------------------------------+
+ * | Data Block 1 |
+ * +-------------------------------------------------+
+ * | ... |
+ * +-------------------------------------------------+
+ * | Data Block n |
+ * +-------------------------------------------------+
+ * | HD Footer (511 bytes) |
+ * +-------------------------------------------------+
+ */
+
+#endif