debuggers.hg

view tools/blktap/blkif.c @ 6649:f59e0163540e

Updates to blktap driver and user code.

Mostly this makes the tap code work again with all of the changes that
have happened to the block drivers recently. We now use a shared page
per VBD (to the driver), and handle control information through the
store. The taplib interfaces have changed to be based around per-vbd
data structures that you can attach arbitrary handlers for.

There is also initial code for a user-level blockback driver, which
aims to get around the use of loopbacks for file-based vbds. Still
plenty of work to do here -- this is a working incremental checkin and
I'm away from this for the next four weeks.

Signed-off-by: Andrew Warfield <andrew.warfield@cl.cam.ac.uk>
author akw27@arcadians.cl.cam.ac.uk
date Sun Sep 04 21:19:44 2005 +0000 (2005-09-04)
parents
children b2f4823b6ff0 b35215021b32 9af349b055e5 3233e7ecfa9f
line source
1 /*
2 * blkif.c
3 *
4 * The blkif interface for blktap. A blkif describes an in-use virtual disk.
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <err.h>
13 #include "blktaplib.h"
15 #if 1
16 #define DPRINTF(_f, _a...) printf ( _f , ## _a )
17 #else
18 #define DPRINTF(_f, _a...) ((void)0)
19 #endif
21 #define BLKIF_HASHSZ 1024
22 #define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1))
24 static blkif_t *blkif_hash[BLKIF_HASHSZ];
26 blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle)
27 {
28 blkif_t *blkif = blkif_hash[BLKIF_HASH(domid, handle)];
29 while ( (blkif != NULL) &&
30 ((blkif->domid != domid) || (blkif->handle != handle)) )
31 blkif = blkif->hash_next;
32 return blkif;
33 }
35 blkif_t *alloc_blkif(domid_t domid)
36 {
37 blkif_t *blkif;
39 blkif = (blkif_t *)malloc(sizeof(blkif_t));
40 if (!blkif)
41 return NULL;
43 memset(blkif, 0, sizeof(*blkif));
44 blkif->domid = domid;
46 return blkif;
47 }
49 static int (*new_blkif_hook)(blkif_t *blkif) = NULL;
50 void register_new_blkif_hook(int (*fn)(blkif_t *blkif))
51 {
52 new_blkif_hook = fn;
53 }
55 int blkif_init(blkif_t *blkif, long int handle, long int pdev,
56 long int readonly)
57 {
58 domid_t domid;
59 blkif_t **pblkif;
61 if (blkif == NULL)
62 return -EINVAL;
64 domid = blkif->domid;
65 blkif->handle = handle;
66 blkif->pdev = pdev;
67 blkif->readonly = readonly;
69 /*
70 * Call out to the new_blkif_hook. The tap application should define this,
71 * and it should return having set blkif->ops
72 *
73 */
74 if (new_blkif_hook == NULL)
75 {
76 warn("Probe detected a new blkif, but no new_blkif_hook!");
77 return -1;
78 }
79 new_blkif_hook(blkif);
81 /* Now wire it in. */
82 pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
83 while ( *pblkif != NULL )
84 {
85 if ( ((*pblkif)->domid == domid) && ((*pblkif)->handle == handle) )
86 {
87 DPRINTF("Could not create blkif: already exists\n");
88 return -1;
89 }
90 pblkif = &(*pblkif)->hash_next;
91 }
92 blkif->hash_next = NULL;
93 *pblkif = blkif;
95 return 0;
96 }
98 void free_blkif(blkif_t *blkif)
99 {
100 blkif_t **pblkif, *curs;
102 pblkif = &blkif_hash[BLKIF_HASH(blkif->domid, blkif->handle)];
103 while ( (curs = *pblkif) != NULL )
104 {
105 if ( blkif == curs )
106 {
107 *pblkif = curs->hash_next;
108 }
109 pblkif = &curs->hash_next;
110 }
111 if (blkif != NULL)
112 free(blkif);
113 }
115 void blkif_register_request_hook(blkif_t *blkif, char *name,
116 int (*rh)(blkif_t *, blkif_request_t *, int))
117 {
118 request_hook_t *rh_ent, **c;
120 rh_ent = (request_hook_t *)malloc(sizeof(request_hook_t));
121 if (!rh_ent)
122 {
123 warn("couldn't allocate a new hook");
124 return;
125 }
127 rh_ent->func = rh;
128 rh_ent->next = NULL;
129 if (asprintf(&rh_ent->name, "%s", name) == -1)
130 {
131 free(rh_ent);
132 warn("couldn't allocate a new hook name");
133 return;
134 }
136 c = &blkif->request_hook_chain;
137 while (*c != NULL) {
138 c = &(*c)->next;
139 }
140 *c = rh_ent;
141 }
143 void blkif_register_response_hook(blkif_t *blkif, char *name,
144 int (*rh)(blkif_t *, blkif_response_t *, int))
145 {
146 response_hook_t *rh_ent, **c;
148 rh_ent = (response_hook_t *)malloc(sizeof(response_hook_t));
149 if (!rh_ent)
150 {
151 warn("couldn't allocate a new hook");
152 return;
153 }
155 rh_ent->func = rh;
156 rh_ent->next = NULL;
157 if (asprintf(&rh_ent->name, "%s", name) == -1)
158 {
159 free(rh_ent);
160 warn("couldn't allocate a new hook name");
161 return;
162 }
164 c = &blkif->response_hook_chain;
165 while (*c != NULL) {
166 c = &(*c)->next;
167 }
168 *c = rh_ent;
169 }
171 void blkif_print_hooks(blkif_t *blkif)
172 {
173 request_hook_t *req_hook;
174 response_hook_t *rsp_hook;
176 DPRINTF("Request Hooks:\n");
177 req_hook = blkif->request_hook_chain;
178 while (req_hook != NULL)
179 {
180 DPRINTF(" [0x%p] %s\n", req_hook->func, req_hook->name);
181 req_hook = req_hook->next;
182 }
184 DPRINTF("Response Hooks:\n");
185 rsp_hook = blkif->response_hook_chain;
186 while (rsp_hook != NULL)
187 {
188 DPRINTF(" [0x%p] %s\n", rsp_hook->func, rsp_hook->name);
189 rsp_hook = rsp_hook->next;
190 }
191 }
194 long int vbd_size(blkif_t *blkif)
195 {
196 return 1000000000;
197 }
199 long int vbd_secsize(blkif_t *blkif)
200 {
201 return 512;
202 }
204 unsigned vbd_info(blkif_t *blkif)
205 {
206 return 0;
207 }
210 void __init_blkif(void)
211 {
212 memset(blkif_hash, 0, sizeof(blkif_hash));
213 }