ia64/xen-unstable

view tools/blktap/drivers/tapdisk.h @ 14085:8407279d3751

[TAPDISK] minor changes to tapdisk and plugins
* open all parent images read-only
* expose parent image names to tapdisk (needed for locking api)
Signed-off-by: Jake Wires <jwires@xensource.com>
author Jake Wires <jwires@xensource.com>
date Thu Feb 22 21:32:17 2007 -0800 (2007-02-22)
parents 3c827d68fa87
children e9bd3267ff23
line source
1 /* tapdisk.h
2 *
3 * Generic disk interface for blktap-based image adapters.
4 *
5 * (c) 2006 Andrew Warfield and Julian Chesterfield
6 *
7 * Some notes on the tap_disk interface:
8 *
9 * tap_disk aims to provide a generic interface to easily implement new
10 * types of image accessors. The structure-of-function-calls is similar
11 * to disk interfaces used in qemu/denali/etc, with the significant
12 * difference being the expectation of asynchronous rather than synchronous
13 * I/O. The asynchronous interface is intended to allow lots of requests to
14 * be pipelined through a disk, without the disk requiring any of its own
15 * threads of control. As such, a batch of requests is delivered to the disk
16 * using:
17 *
18 * td_queue_[read,write]()
19 *
20 * and passing in a completion callback, which the disk is responsible for
21 * tracking. The end of a back is marked with a call to:
22 *
23 * td_submit()
24 *
25 * The disk implementation must provide a file handle, which is used to
26 * indicate that it needs to do work. tapdisk will add this file handle
27 * (returned from td_get_fd()) to it's poll set, and will call into the disk
28 * using td_do_callbacks() whenever there is data pending.
29 *
30 * Two disk implementations demonstrate how this interface may be used to
31 * implement disks with both asynchronous and synchronous calls. block-aio.c
32 * maps this interface down onto the linux libaio calls, while block-sync uses
33 * normal posix read/write.
34 *
35 * A few things to realize about the sync case, which doesn't need to defer
36 * io completions:
37 *
38 * - td_queue_[read,write]() call read/write directly, and then call the
39 * callback immediately. The MUST then return a value greater than 0
40 * in order to tell tapdisk that requests have finished early, and to
41 * force responses to be kicked to the clents.
42 *
43 * - The fd used for poll is an otherwise unused pipe, which allows poll to
44 * be safely called without ever returning anything.
45 *
46 * NOTE: tapdisk uses the number of sectors submitted per request as a
47 * ref count. Plugins must use the callback function to communicate the
48 * completion--or error--of every sector submitted to them.
49 *
50 * td_get_parent_id returns:
51 * 0 if parent id successfully retrieved
52 * TD_NO_PARENT if no parent exists
53 * -errno on error
54 */
56 #ifndef TAPDISK_H_
57 #define TAPDISK_H_
59 #include <stdint.h>
60 #include <syslog.h>
61 #include "blktaplib.h"
63 /*If enabled, log all debug messages to syslog*/
64 #if 1
65 #define DPRINTF(_f, _a...) syslog( LOG_DEBUG, _f , ## _a )
66 #else
67 #define DPRINTF(_f, _a...) ((void)0)
68 #endif
70 /* Things disks need to know about, these should probably be in a higher-level
71 * header. */
72 #define MAX_SEGMENTS_PER_REQ 11
73 #define SECTOR_SHIFT 9
74 #define DEFAULT_SECTOR_SIZE 512
76 #define MAX_IOFD 2
78 #define BLK_NOT_ALLOCATED 99
79 #define TD_NO_PARENT 1
81 typedef uint32_t td_flag_t;
83 #define TD_RDONLY 1
85 struct td_state;
86 struct tap_disk;
88 struct disk_id {
89 char *name;
90 int drivertype;
91 };
93 struct disk_driver {
94 int early;
95 char *name;
96 void *private;
97 int io_fd[MAX_IOFD];
98 struct tap_disk *drv;
99 struct td_state *td_state;
100 struct disk_driver *next;
101 };
103 /* This structure represents the state of an active virtual disk. */
104 struct td_state {
105 struct disk_driver *disks;
106 void *blkif;
107 void *image;
108 void *ring_info;
109 void *fd_entry;
110 unsigned long sector_size;
111 unsigned long long size;
112 unsigned int info;
113 };
115 /* Prototype of the callback to activate as requests complete. */
116 typedef int (*td_callback_t)(struct disk_driver *dd, int res, uint64_t sector,
117 int nb_sectors, int id, void *private);
119 /* Structure describing the interface to a virtual disk implementation. */
120 /* See note at the top of this file describing this interface. */
121 struct tap_disk {
122 const char *disk_type;
123 int private_data_size;
124 int (*td_open) (struct disk_driver *dd,
125 const char *name, td_flag_t flags);
126 int (*td_queue_read) (struct disk_driver *dd, uint64_t sector,
127 int nb_sectors, char *buf, td_callback_t cb,
128 int id, void *prv);
129 int (*td_queue_write) (struct disk_driver *dd, uint64_t sector,
130 int nb_sectors, char *buf, td_callback_t cb,
131 int id, void *prv);
132 int (*td_submit) (struct disk_driver *dd);
133 int (*td_close) (struct disk_driver *dd);
134 int (*td_do_callbacks) (struct disk_driver *dd, int sid);
135 int (*td_get_parent_id) (struct disk_driver *dd, struct disk_id *id);
136 int (*td_validate_parent)(struct disk_driver *dd,
137 struct disk_driver *p, td_flag_t flags);
138 };
140 typedef struct disk_info {
141 int idnum;
142 char name[50]; /* e.g. "RAMDISK" */
143 char handle[10]; /* xend handle, e.g. 'ram' */
144 int single_handler; /* is there a single controller for all */
145 /* instances of disk type? */
146 #ifdef TAPDISK
147 struct tap_disk *drv;
148 #endif
149 } disk_info_t;
151 void debug_fe_ring(struct td_state *s);
153 extern struct tap_disk tapdisk_aio;
154 extern struct tap_disk tapdisk_sync;
155 extern struct tap_disk tapdisk_vmdk;
156 extern struct tap_disk tapdisk_ram;
157 extern struct tap_disk tapdisk_qcow;
159 #define MAX_DISK_TYPES 20
161 #define DISK_TYPE_AIO 0
162 #define DISK_TYPE_SYNC 1
163 #define DISK_TYPE_VMDK 2
164 #define DISK_TYPE_RAM 3
165 #define DISK_TYPE_QCOW 4
168 /*Define Individual Disk Parameters here */
169 static disk_info_t aio_disk = {
170 DISK_TYPE_AIO,
171 "raw image (aio)",
172 "aio",
173 0,
174 #ifdef TAPDISK
175 &tapdisk_aio,
176 #endif
177 };
179 static disk_info_t sync_disk = {
180 DISK_TYPE_SYNC,
181 "raw image (sync)",
182 "sync",
183 0,
184 #ifdef TAPDISK
185 &tapdisk_sync,
186 #endif
187 };
189 static disk_info_t vmdk_disk = {
190 DISK_TYPE_VMDK,
191 "vmware image (vmdk)",
192 "vmdk",
193 1,
194 #ifdef TAPDISK
195 &tapdisk_vmdk,
196 #endif
197 };
199 static disk_info_t ram_disk = {
200 DISK_TYPE_RAM,
201 "ramdisk image (ram)",
202 "ram",
203 1,
204 #ifdef TAPDISK
205 &tapdisk_ram,
206 #endif
207 };
209 static disk_info_t qcow_disk = {
210 DISK_TYPE_QCOW,
211 "qcow disk (qcow)",
212 "qcow",
213 0,
214 #ifdef TAPDISK
215 &tapdisk_qcow,
216 #endif
217 };
219 /*Main disk info array */
220 static disk_info_t *dtypes[] = {
221 &aio_disk,
222 &sync_disk,
223 &vmdk_disk,
224 &ram_disk,
225 &qcow_disk,
226 };
228 typedef struct driver_list_entry {
229 struct blkif *blkif;
230 struct driver_list_entry **pprev, *next;
231 } driver_list_entry_t;
233 typedef struct fd_list_entry {
234 int cookie;
235 int tap_fd;
236 struct td_state *s;
237 struct fd_list_entry **pprev, *next;
238 } fd_list_entry_t;
240 int qcow_create(const char *filename, uint64_t total_size,
241 const char *backing_file, int flags);
242 #endif /*TAPDISK_H_*/