ia64/xen-unstable

view tools/blktap/blkif.c @ 6946:e703abaf6e3d

Add behaviour to the remove methods to remove the transaction's path itself. This allows us to write Remove(path) to remove the specified path rather than having to slice the path ourselves.
author emellor@ewan
date Sun Sep 18 14:42:13 2005 +0100 (2005-09-18)
parents 3233e7ecfa9f
children 06d84bf87159
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 }