debuggers.hg

view tools/blktap2/drivers/tapdisk-server.c @ 22848:6341fe0f4e5a

Added tag 4.1.0-rc2 for changeset 9dca60d88c63
author Keir Fraser <keir@xen.org>
date Tue Jan 25 14:06:55 2011 +0000 (2011-01-25)
parents 63d0f5348af2
children
line source
1 /*
2 * Copyright (c) 2008, XenSource Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of XenSource Inc. nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 #include <stdio.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <sys/ioctl.h>
33 #include <sys/signal.h>
35 #include "tapdisk-utils.h"
36 #include "tapdisk-server.h"
37 #include "tapdisk-driver.h"
38 #include "tapdisk-interface.h"
40 #define DBG(_level, _f, _a...) tlog_write(_level, _f, ##_a)
41 #define ERR(_err, _f, _a...) tlog_error(_err, _f, ##_a)
43 tapdisk_server_t server;
45 #define tapdisk_server_for_each_vbd(vbd, tmp) \
46 list_for_each_entry_safe(vbd, tmp, &server.vbds, next)
48 td_image_t *
49 tapdisk_server_get_shared_image(td_image_t *image)
50 {
51 td_vbd_t *vbd, *tmpv;
52 td_image_t *img, *tmpi;
54 if (!td_flag_test(image->flags, TD_OPEN_SHAREABLE))
55 return NULL;
57 tapdisk_server_for_each_vbd(vbd, tmpv)
58 tapdisk_vbd_for_each_image(vbd, img, tmpi)
59 if (img->type == image->type &&
60 !strcmp(img->name, image->name))
61 return img;
63 return NULL;
64 }
66 struct list_head *
67 tapdisk_server_get_all_vbds(void)
68 {
69 return &server.vbds;
70 }
72 td_vbd_t *
73 tapdisk_server_get_vbd(uint16_t uuid)
74 {
75 td_vbd_t *vbd, *tmp;
77 tapdisk_server_for_each_vbd(vbd, tmp)
78 if (vbd->uuid == uuid)
79 return vbd;
81 return NULL;
82 }
84 void
85 tapdisk_server_add_vbd(td_vbd_t *vbd)
86 {
87 list_add_tail(&vbd->next, &server.vbds);
88 }
90 void
91 tapdisk_server_remove_vbd(td_vbd_t *vbd)
92 {
93 list_del(&vbd->next);
94 INIT_LIST_HEAD(&vbd->next);
95 tapdisk_server_check_state();
96 }
98 void
99 tapdisk_server_queue_tiocb(struct tiocb *tiocb)
100 {
101 tapdisk_queue_tiocb(&server.aio_queue, tiocb);
102 }
104 void
105 tapdisk_server_debug(void)
106 {
107 td_vbd_t *vbd, *tmp;
109 tapdisk_debug_queue(&server.aio_queue);
111 tapdisk_server_for_each_vbd(vbd, tmp)
112 tapdisk_vbd_debug(vbd);
114 tlog_flush();
115 }
117 void
118 tapdisk_server_check_state(void)
119 {
120 if (list_empty(&server.vbds))
121 server.run = 0;
122 }
124 event_id_t
125 tapdisk_server_register_event(char mode, int fd,
126 int timeout, event_cb_t cb, void *data)
127 {
128 return scheduler_register_event(&server.scheduler,
129 mode, fd, timeout, cb, data);
130 }
132 void
133 tapdisk_server_unregister_event(event_id_t event)
134 {
135 return scheduler_unregister_event(&server.scheduler, event);
136 }
138 void
139 tapdisk_server_set_max_timeout(int seconds)
140 {
141 scheduler_set_max_timeout(&server.scheduler, seconds);
142 }
144 static void
145 tapdisk_server_assert_locks(void)
146 {
148 }
150 static void
151 tapdisk_server_set_retry_timeout(void)
152 {
153 td_vbd_t *vbd, *tmp;
155 tapdisk_server_for_each_vbd(vbd, tmp)
156 if (tapdisk_vbd_retry_needed(vbd)) {
157 tapdisk_server_set_max_timeout(TD_VBD_RETRY_INTERVAL);
158 return;
159 }
160 }
162 static void
163 tapdisk_server_check_progress(void)
164 {
165 struct timeval now;
166 td_vbd_t *vbd, *tmp;
168 gettimeofday(&now, NULL);
170 tapdisk_server_for_each_vbd(vbd, tmp)
171 tapdisk_vbd_check_progress(vbd);
172 }
174 static void
175 tapdisk_server_submit_tiocbs(void)
176 {
177 tapdisk_submit_all_tiocbs(&server.aio_queue);
178 }
180 static void
181 tapdisk_server_kick_responses(void)
182 {
183 int n;
184 td_vbd_t *vbd, *tmp;
186 tapdisk_server_for_each_vbd(vbd, tmp)
187 tapdisk_vbd_kick(vbd);
188 }
190 static void
191 tapdisk_server_check_vbds(void)
192 {
193 td_vbd_t *vbd, *tmp;
195 tapdisk_server_for_each_vbd(vbd, tmp)
196 tapdisk_vbd_check_state(vbd);
197 }
199 static void
200 tapdisk_server_stop_vbds(void)
201 {
202 td_vbd_t *vbd, *tmp;
204 tapdisk_server_for_each_vbd(vbd, tmp)
205 tapdisk_vbd_kill_queue(vbd);
206 }
208 static int
209 tapdisk_server_init_aio(void)
210 {
211 return tapdisk_init_queue(&server.aio_queue, TAPDISK_TIOCBS,
212 TIO_DRV_LIO, NULL);
213 }
215 static void
216 tapdisk_server_close_aio(void)
217 {
218 tapdisk_free_queue(&server.aio_queue);
219 }
221 static void
222 tapdisk_server_close(void)
223 {
224 tapdisk_server_close_aio();
225 }
227 void
228 tapdisk_server_iterate(void)
229 {
230 int ret;
232 tapdisk_server_assert_locks();
233 tapdisk_server_set_retry_timeout();
234 tapdisk_server_check_progress();
236 ret = scheduler_wait_for_events(&server.scheduler);
237 if (ret < 0)
238 DBG(TLOG_WARN, "server wait returned %d\n", ret);
240 tapdisk_server_check_vbds();
241 tapdisk_server_submit_tiocbs();
242 tapdisk_server_kick_responses();
243 }
245 static void
246 __tapdisk_server_run(void)
247 {
248 while (server.run)
249 tapdisk_server_iterate();
250 }
252 static void
253 tapdisk_server_signal_handler(int signal)
254 {
255 td_vbd_t *vbd, *tmp;
256 static int xfsz_error_sent = 0;
258 switch (signal) {
259 case SIGBUS:
260 case SIGINT:
261 tapdisk_server_for_each_vbd(vbd, tmp)
262 tapdisk_vbd_close(vbd);
263 break;
265 case SIGXFSZ:
266 ERR(EFBIG, "received SIGXFSZ");
267 tapdisk_server_stop_vbds();
268 if (xfsz_error_sent)
269 break;
271 xfsz_error_sent = 1;
272 break;
274 case SIGUSR1:
275 tapdisk_server_debug();
276 break;
277 }
278 }
280 int
281 tapdisk_server_init(void)
282 {
283 memset(&server, 0, sizeof(server));
284 INIT_LIST_HEAD(&server.vbds);
286 scheduler_initialize(&server.scheduler);
288 return 0;
289 }
291 int
292 tapdisk_server_complete(void)
293 {
294 int err;
296 err = tapdisk_server_init_aio();
297 if (err)
298 goto fail;
300 server.run = 1;
302 return 0;
304 fail:
305 tapdisk_server_close_aio();
306 return err;
307 }
309 int
310 tapdisk_server_initialize(void)
311 {
312 int err;
314 tapdisk_server_init();
316 err = tapdisk_server_complete();
317 if (err)
318 goto fail;
320 return 0;
322 fail:
323 tapdisk_server_close();
324 return err;
325 }
327 int
328 tapdisk_server_run()
329 {
330 int err;
332 err = tapdisk_set_resource_limits();
333 if (err)
334 return err;
336 signal(SIGBUS, tapdisk_server_signal_handler);
337 signal(SIGINT, tapdisk_server_signal_handler);
338 signal(SIGUSR1, tapdisk_server_signal_handler);
339 signal(SIGXFSZ, tapdisk_server_signal_handler);
341 __tapdisk_server_run();
342 tapdisk_server_close();
344 return 0;
345 }