ia64/xen-unstable

view tools/blktap/blkif.c @ 7238:971e7c7411b3

Raise an exception if an error appears on the pipes to our children, and make
sure that the child's pipes are closed even under that exception. Move the
handling of POLLHUP to the end of the loop, so that we guarantee to read any
remaining data from the child if POLLHUP and POLLIN appear at the same time.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@ewan
date Thu Oct 06 10:13:11 2005 +0100 (2005-10-06)
parents 06d84bf87159
children fcb7e5616102
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 }