ia64/xen-unstable

view linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c @ 7594:a7129a40f239

From Gerd Knorr <kraxel@suse.de>:

Watch events may get lost, the xenstored response races against the new
watch being added to the watch list in register_xenbus_watch(). Fixed
by adding the watch to the list unconditionally, and remove it in the
error case.

That one fixes the network issues I'm seeing. Due to the race the
"online" hotplug event for the vif backend was lost sometimes.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Mon Oct 31 17:03:13 2005 +0100 (2005-10-31)
parents eee0489b3a17
children cc5450d52e49
line source
1 /******************************************************************************
2 * xenbus_xs.c
3 *
4 * This is the kernel equivalent of the "xs" library. We don't need everything
5 * and we use xenbus_comms for communication.
6 *
7 * Copyright (C) 2005 Rusty Russell, IBM Corporation
8 *
9 * This file may be distributed separately from the Linux kernel, or
10 * incorporated into other software packages, subject to the following license:
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this source file (the "Software"), to deal in the Software without
14 * restriction, including without limitation the rights to use, copy, modify,
15 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
16 * and to permit persons to whom the Software is furnished to do so, subject to
17 * the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * IN THE SOFTWARE.
29 */
31 #include <linux/unistd.h>
32 #include <linux/errno.h>
33 #include <linux/types.h>
34 #include <linux/uio.h>
35 #include <linux/kernel.h>
36 #include <linux/string.h>
37 #include <linux/err.h>
38 #include <linux/slab.h>
39 #include <linux/fcntl.h>
40 #include <linux/kthread.h>
41 #include <asm-xen/xenbus.h>
42 #include "xenbus_comms.h"
44 #define streq(a, b) (strcmp((a), (b)) == 0)
46 struct xs_stored_msg {
47 struct list_head list;
49 struct xsd_sockmsg hdr;
51 union {
52 /* Queued replies. */
53 struct {
54 char *body;
55 } reply;
57 /* Queued watch events. */
58 struct {
59 struct xenbus_watch *handle;
60 char **vec;
61 unsigned int vec_size;
62 } watch;
63 } u;
64 };
66 struct xs_handle {
67 /* A list of replies. Currently only one will ever be outstanding. */
68 struct list_head reply_list;
69 spinlock_t reply_lock;
70 wait_queue_head_t reply_waitq;
72 /* One request at a time. */
73 struct semaphore request_mutex;
75 /* Protect transactions against save/restore. */
76 struct rw_semaphore suspend_mutex;
77 };
79 static struct xs_handle xs_state;
81 /* List of registered watches, and a lock to protect it. */
82 static LIST_HEAD(watches);
83 static DEFINE_SPINLOCK(watches_lock);
85 /* List of pending watch callback events, and a lock to protect it. */
86 static LIST_HEAD(watch_events);
87 static DEFINE_SPINLOCK(watch_events_lock);
89 /*
90 * Details of the xenwatch callback kernel thread. The thread waits on the
91 * watch_events_waitq for work to do (queued on watch_events list). When it
92 * wakes up it acquires the xenwatch_mutex before reading the list and
93 * carrying out work.
94 */
95 static pid_t xenwatch_pid;
96 /* static */ DECLARE_MUTEX(xenwatch_mutex);
97 static DECLARE_WAIT_QUEUE_HEAD(watch_events_waitq);
99 static int get_error(const char *errorstring)
100 {
101 unsigned int i;
103 for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++) {
104 if (i == ARRAY_SIZE(xsd_errors) - 1) {
105 printk(KERN_WARNING
106 "XENBUS xen store gave: unknown error %s",
107 errorstring);
108 return EINVAL;
109 }
110 }
111 return xsd_errors[i].errnum;
112 }
114 static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
115 {
116 struct xs_stored_msg *msg;
117 char *body;
119 spin_lock(&xs_state.reply_lock);
121 while (list_empty(&xs_state.reply_list)) {
122 spin_unlock(&xs_state.reply_lock);
123 wait_event_interruptible(xs_state.reply_waitq,
124 !list_empty(&xs_state.reply_list));
125 spin_lock(&xs_state.reply_lock);
126 }
128 msg = list_entry(xs_state.reply_list.next,
129 struct xs_stored_msg, list);
130 list_del(&msg->list);
132 spin_unlock(&xs_state.reply_lock);
134 *type = msg->hdr.type;
135 if (len)
136 *len = msg->hdr.len;
137 body = msg->u.reply.body;
139 kfree(msg);
141 return body;
142 }
144 /* Emergency write. */
145 void xenbus_debug_write(const char *str, unsigned int count)
146 {
147 struct xsd_sockmsg msg = { 0 };
149 msg.type = XS_DEBUG;
150 msg.len = sizeof("print") + count + 1;
152 down(&xs_state.request_mutex);
153 xb_write(&msg, sizeof(msg));
154 xb_write("print", sizeof("print"));
155 xb_write(str, count);
156 xb_write("", 1);
157 up(&xs_state.request_mutex);
158 }
160 void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
161 {
162 void *ret;
163 struct xsd_sockmsg req_msg = *msg;
164 int err;
166 if (req_msg.type == XS_TRANSACTION_START)
167 down_read(&xs_state.suspend_mutex);
169 down(&xs_state.request_mutex);
171 err = xb_write(msg, sizeof(*msg) + msg->len);
172 if (err) {
173 msg->type = XS_ERROR;
174 ret = ERR_PTR(err);
175 } else {
176 ret = read_reply(&msg->type, &msg->len);
177 }
179 up(&xs_state.request_mutex);
181 if ((msg->type == XS_TRANSACTION_END) ||
182 ((req_msg.type == XS_TRANSACTION_START) &&
183 (msg->type == XS_ERROR)))
184 up_read(&xs_state.suspend_mutex);
186 return ret;
187 }
189 /* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */
190 static void *xs_talkv(struct xenbus_transaction *t,
191 enum xsd_sockmsg_type type,
192 const struct kvec *iovec,
193 unsigned int num_vecs,
194 unsigned int *len)
195 {
196 struct xsd_sockmsg msg;
197 void *ret = NULL;
198 unsigned int i;
199 int err;
201 msg.tx_id = (u32)(unsigned long)t;
202 msg.type = type;
203 msg.len = 0;
204 for (i = 0; i < num_vecs; i++)
205 msg.len += iovec[i].iov_len;
207 down(&xs_state.request_mutex);
209 err = xb_write(&msg, sizeof(msg));
210 if (err) {
211 up(&xs_state.request_mutex);
212 return ERR_PTR(err);
213 }
215 for (i = 0; i < num_vecs; i++) {
216 err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
217 if (err) {
218 up(&xs_state.request_mutex);
219 return ERR_PTR(err);
220 }
221 }
223 ret = read_reply(&msg.type, len);
225 up(&xs_state.request_mutex);
227 if (IS_ERR(ret))
228 return ret;
230 if (msg.type == XS_ERROR) {
231 err = get_error(ret);
232 kfree(ret);
233 return ERR_PTR(-err);
234 }
236 BUG_ON(msg.type != type);
237 return ret;
238 }
240 /* Simplified version of xs_talkv: single message. */
241 static void *xs_single(struct xenbus_transaction *t,
242 enum xsd_sockmsg_type type,
243 const char *string,
244 unsigned int *len)
245 {
246 struct kvec iovec;
248 iovec.iov_base = (void *)string;
249 iovec.iov_len = strlen(string) + 1;
250 return xs_talkv(t, type, &iovec, 1, len);
251 }
253 /* Many commands only need an ack, don't care what it says. */
254 static int xs_error(char *reply)
255 {
256 if (IS_ERR(reply))
257 return PTR_ERR(reply);
258 kfree(reply);
259 return 0;
260 }
262 static unsigned int count_strings(const char *strings, unsigned int len)
263 {
264 unsigned int num;
265 const char *p;
267 for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
268 num++;
270 return num;
271 }
273 /* Return the path to dir with /name appended. Buffer must be kfree()'ed. */
274 static char *join(const char *dir, const char *name)
275 {
276 char *buffer;
278 buffer = kmalloc(strlen(dir) + strlen("/") + strlen(name) + 1,
279 GFP_KERNEL);
280 if (buffer == NULL)
281 return ERR_PTR(-ENOMEM);
283 strcpy(buffer, dir);
284 if (!streq(name, "")) {
285 strcat(buffer, "/");
286 strcat(buffer, name);
287 }
289 return buffer;
290 }
292 static char **split(char *strings, unsigned int len, unsigned int *num)
293 {
294 char *p, **ret;
296 /* Count the strings. */
297 *num = count_strings(strings, len);
299 /* Transfer to one big alloc for easy freeing. */
300 ret = kmalloc(*num * sizeof(char *) + len, GFP_KERNEL);
301 if (!ret) {
302 kfree(strings);
303 return ERR_PTR(-ENOMEM);
304 }
305 memcpy(&ret[*num], strings, len);
306 kfree(strings);
308 strings = (char *)&ret[*num];
309 for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
310 ret[(*num)++] = p;
312 return ret;
313 }
315 char **xenbus_directory(struct xenbus_transaction *t,
316 const char *dir, const char *node, unsigned int *num)
317 {
318 char *strings, *path;
319 unsigned int len;
321 path = join(dir, node);
322 if (IS_ERR(path))
323 return (char **)path;
325 strings = xs_single(t, XS_DIRECTORY, path, &len);
326 kfree(path);
327 if (IS_ERR(strings))
328 return (char **)strings;
330 return split(strings, len, num);
331 }
332 EXPORT_SYMBOL(xenbus_directory);
334 /* Check if a path exists. Return 1 if it does. */
335 int xenbus_exists(struct xenbus_transaction *t,
336 const char *dir, const char *node)
337 {
338 char **d;
339 int dir_n;
341 d = xenbus_directory(t, dir, node, &dir_n);
342 if (IS_ERR(d))
343 return 0;
344 kfree(d);
345 return 1;
346 }
347 EXPORT_SYMBOL(xenbus_exists);
349 /* Get the value of a single file.
350 * Returns a kmalloced value: call free() on it after use.
351 * len indicates length in bytes.
352 */
353 void *xenbus_read(struct xenbus_transaction *t,
354 const char *dir, const char *node, unsigned int *len)
355 {
356 char *path;
357 void *ret;
359 path = join(dir, node);
360 if (IS_ERR(path))
361 return (void *)path;
363 ret = xs_single(t, XS_READ, path, len);
364 kfree(path);
365 return ret;
366 }
367 EXPORT_SYMBOL(xenbus_read);
369 /* Write the value of a single file.
370 * Returns -err on failure.
371 */
372 int xenbus_write(struct xenbus_transaction *t,
373 const char *dir, const char *node, const char *string)
374 {
375 const char *path;
376 struct kvec iovec[2];
377 int ret;
379 path = join(dir, node);
380 if (IS_ERR(path))
381 return PTR_ERR(path);
383 iovec[0].iov_base = (void *)path;
384 iovec[0].iov_len = strlen(path) + 1;
385 iovec[1].iov_base = (void *)string;
386 iovec[1].iov_len = strlen(string);
388 ret = xs_error(xs_talkv(t, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
389 kfree(path);
390 return ret;
391 }
392 EXPORT_SYMBOL(xenbus_write);
394 /* Create a new directory. */
395 int xenbus_mkdir(struct xenbus_transaction *t,
396 const char *dir, const char *node)
397 {
398 char *path;
399 int ret;
401 path = join(dir, node);
402 if (IS_ERR(path))
403 return PTR_ERR(path);
405 ret = xs_error(xs_single(t, XS_MKDIR, path, NULL));
406 kfree(path);
407 return ret;
408 }
409 EXPORT_SYMBOL(xenbus_mkdir);
411 /* Destroy a file or directory (directories must be empty). */
412 int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node)
413 {
414 char *path;
415 int ret;
417 path = join(dir, node);
418 if (IS_ERR(path))
419 return PTR_ERR(path);
421 ret = xs_error(xs_single(t, XS_RM, path, NULL));
422 kfree(path);
423 return ret;
424 }
425 EXPORT_SYMBOL(xenbus_rm);
427 /* Start a transaction: changes by others will not be seen during this
428 * transaction, and changes will not be visible to others until end.
429 */
430 struct xenbus_transaction *xenbus_transaction_start(void)
431 {
432 char *id_str;
433 unsigned long id;
435 down_read(&xs_state.suspend_mutex);
437 id_str = xs_single(NULL, XS_TRANSACTION_START, "", NULL);
438 if (IS_ERR(id_str)) {
439 up_read(&xs_state.suspend_mutex);
440 return (struct xenbus_transaction *)id_str;
441 }
443 id = simple_strtoul(id_str, NULL, 0);
444 kfree(id_str);
446 return (struct xenbus_transaction *)id;
447 }
448 EXPORT_SYMBOL(xenbus_transaction_start);
450 /* End a transaction.
451 * If abandon is true, transaction is discarded instead of committed.
452 */
453 int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
454 {
455 char abortstr[2];
456 int err;
458 if (abort)
459 strcpy(abortstr, "F");
460 else
461 strcpy(abortstr, "T");
463 err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL));
465 up_read(&xs_state.suspend_mutex);
467 return err;
468 }
469 EXPORT_SYMBOL(xenbus_transaction_end);
471 /* Single read and scanf: returns -errno or num scanned. */
472 int xenbus_scanf(struct xenbus_transaction *t,
473 const char *dir, const char *node, const char *fmt, ...)
474 {
475 va_list ap;
476 int ret;
477 char *val;
479 val = xenbus_read(t, dir, node, NULL);
480 if (IS_ERR(val))
481 return PTR_ERR(val);
483 va_start(ap, fmt);
484 ret = vsscanf(val, fmt, ap);
485 va_end(ap);
486 kfree(val);
487 /* Distinctive errno. */
488 if (ret == 0)
489 return -ERANGE;
490 return ret;
491 }
492 EXPORT_SYMBOL(xenbus_scanf);
494 /* Single printf and write: returns -errno or 0. */
495 int xenbus_printf(struct xenbus_transaction *t,
496 const char *dir, const char *node, const char *fmt, ...)
497 {
498 va_list ap;
499 int ret;
500 #define PRINTF_BUFFER_SIZE 4096
501 char *printf_buffer;
503 printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
504 if (printf_buffer == NULL)
505 return -ENOMEM;
507 va_start(ap, fmt);
508 ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap);
509 va_end(ap);
511 BUG_ON(ret > PRINTF_BUFFER_SIZE-1);
512 ret = xenbus_write(t, dir, node, printf_buffer);
514 kfree(printf_buffer);
516 return ret;
517 }
518 EXPORT_SYMBOL(xenbus_printf);
520 /**
521 * Return the path to the error node for the given device, or NULL on failure.
522 * If the value returned is non-NULL, then it is the caller's to kfree.
523 */
524 static char *error_path(struct xenbus_device *dev)
525 {
526 char *path_buffer = kmalloc(strlen("error/") + strlen(dev->nodename) +
527 1, GFP_KERNEL);
528 if (path_buffer == NULL) {
529 return NULL;
530 }
532 strcpy(path_buffer, "error/");
533 strcpy(path_buffer + strlen("error/"), dev->nodename);
535 return path_buffer;
536 }
538 /* Report a (negative) errno into the store, with explanation. */
539 void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...)
540 {
541 va_list ap;
542 int ret;
543 unsigned int len;
544 char *printf_buffer = NULL, *path_buffer = NULL;
546 printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
547 if (printf_buffer == NULL)
548 goto fail;
550 len = sprintf(printf_buffer, "%i ", -err);
551 va_start(ap, fmt);
552 ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
553 va_end(ap);
555 BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
556 dev->has_error = 1;
558 path_buffer = error_path(dev);
560 if (path_buffer == NULL) {
561 printk("xenbus: failed to write error node for %s (%s)\n",
562 dev->nodename, printf_buffer);
563 goto fail;
564 }
566 if (xenbus_write(NULL, path_buffer, "error", printf_buffer) != 0) {
567 printk("xenbus: failed to write error node for %s (%s)\n",
568 dev->nodename, printf_buffer);
569 goto fail;
570 }
572 fail:
573 if (printf_buffer)
574 kfree(printf_buffer);
575 if (path_buffer)
576 kfree(path_buffer);
577 }
578 EXPORT_SYMBOL(xenbus_dev_error);
580 /* Clear any error. */
581 void xenbus_dev_ok(struct xenbus_device *dev)
582 {
583 if (dev->has_error) {
584 char *path_buffer = error_path(dev);
586 if (path_buffer == NULL) {
587 printk("xenbus: failed to clear error node for %s\n",
588 dev->nodename);
589 return;
590 }
592 if (xenbus_rm(NULL, path_buffer, "error") != 0)
593 printk("xenbus: failed to clear error node for %s\n",
594 dev->nodename);
595 else
596 dev->has_error = 0;
598 kfree(path_buffer);
599 }
600 }
601 EXPORT_SYMBOL(xenbus_dev_ok);
603 /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
604 int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
605 {
606 va_list ap;
607 const char *name;
608 int ret = 0;
610 va_start(ap, dir);
611 while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
612 const char *fmt = va_arg(ap, char *);
613 void *result = va_arg(ap, void *);
614 char *p;
616 p = xenbus_read(t, dir, name, NULL);
617 if (IS_ERR(p)) {
618 ret = PTR_ERR(p);
619 break;
620 }
621 if (fmt) {
622 if (sscanf(p, fmt, result) == 0)
623 ret = -EINVAL;
624 kfree(p);
625 } else
626 *(char **)result = p;
627 }
628 va_end(ap);
629 return ret;
630 }
631 EXPORT_SYMBOL(xenbus_gather);
633 static int xs_watch(const char *path, const char *token)
634 {
635 struct kvec iov[2];
637 iov[0].iov_base = (void *)path;
638 iov[0].iov_len = strlen(path) + 1;
639 iov[1].iov_base = (void *)token;
640 iov[1].iov_len = strlen(token) + 1;
642 return xs_error(xs_talkv(NULL, XS_WATCH, iov,
643 ARRAY_SIZE(iov), NULL));
644 }
646 static int xs_unwatch(const char *path, const char *token)
647 {
648 struct kvec iov[2];
650 iov[0].iov_base = (char *)path;
651 iov[0].iov_len = strlen(path) + 1;
652 iov[1].iov_base = (char *)token;
653 iov[1].iov_len = strlen(token) + 1;
655 return xs_error(xs_talkv(NULL, XS_UNWATCH, iov,
656 ARRAY_SIZE(iov), NULL));
657 }
659 static struct xenbus_watch *find_watch(const char *token)
660 {
661 struct xenbus_watch *i, *cmp;
663 cmp = (void *)simple_strtoul(token, NULL, 16);
665 list_for_each_entry(i, &watches, list)
666 if (i == cmp)
667 return i;
669 return NULL;
670 }
672 /* Register callback to watch this node. */
673 int register_xenbus_watch(struct xenbus_watch *watch)
674 {
675 /* Pointer in ascii is the token. */
676 char token[sizeof(watch) * 2 + 1];
677 int err;
679 sprintf(token, "%lX", (long)watch);
681 down_read(&xs_state.suspend_mutex);
683 spin_lock(&watches_lock);
684 BUG_ON(find_watch(token));
685 list_add(&watch->list, &watches);
686 spin_unlock(&watches_lock);
688 err = xs_watch(watch->node, token);
690 /* Ignore errors due to multiple registration. */
691 if ((err != 0) && (err != -EEXIST)) {
692 spin_lock(&watches_lock);
693 list_del(&watch->list);
694 spin_unlock(&watches_lock);
695 }
697 up_read(&xs_state.suspend_mutex);
699 return err;
700 }
701 EXPORT_SYMBOL(register_xenbus_watch);
703 void unregister_xenbus_watch(struct xenbus_watch *watch)
704 {
705 struct xs_stored_msg *msg, *tmp;
706 char token[sizeof(watch) * 2 + 1];
707 int err;
709 sprintf(token, "%lX", (long)watch);
711 down_read(&xs_state.suspend_mutex);
713 spin_lock(&watches_lock);
714 BUG_ON(!find_watch(token));
715 list_del(&watch->list);
716 spin_unlock(&watches_lock);
718 err = xs_unwatch(watch->node, token);
719 if (err)
720 printk(KERN_WARNING
721 "XENBUS Failed to release watch %s: %i\n",
722 watch->node, err);
724 up_read(&xs_state.suspend_mutex);
726 /* Cancel pending watch events. */
727 spin_lock(&watch_events_lock);
728 list_for_each_entry_safe(msg, tmp, &watch_events, list) {
729 if (msg->u.watch.handle != watch)
730 continue;
731 list_del(&msg->list);
732 kfree(msg->u.watch.vec);
733 kfree(msg);
734 }
735 spin_unlock(&watch_events_lock);
737 /* Flush any currently-executing callback, unless we are it. :-) */
738 if (current->pid != xenwatch_pid) {
739 down(&xenwatch_mutex);
740 up(&xenwatch_mutex);
741 }
742 }
743 EXPORT_SYMBOL(unregister_xenbus_watch);
745 void xs_suspend(void)
746 {
747 down_write(&xs_state.suspend_mutex);
748 down(&xs_state.request_mutex);
749 }
751 void xs_resume(void)
752 {
753 struct xenbus_watch *watch;
754 char token[sizeof(watch) * 2 + 1];
756 up(&xs_state.request_mutex);
758 /* No need for watches_lock: the suspend_mutex is sufficient. */
759 list_for_each_entry(watch, &watches, list) {
760 sprintf(token, "%lX", (long)watch);
761 xs_watch(watch->node, token);
762 }
764 up_write(&xs_state.suspend_mutex);
765 }
767 static int xenwatch_thread(void *unused)
768 {
769 struct list_head *ent;
770 struct xs_stored_msg *msg;
772 for (;;) {
773 wait_event_interruptible(watch_events_waitq,
774 !list_empty(&watch_events));
776 down(&xenwatch_mutex);
778 spin_lock(&watch_events_lock);
779 ent = watch_events.next;
780 if (ent != &watch_events)
781 list_del(ent);
782 spin_unlock(&watch_events_lock);
784 if (ent != &watch_events) {
785 msg = list_entry(ent, struct xs_stored_msg, list);
786 msg->u.watch.handle->callback(
787 msg->u.watch.handle,
788 (const char **)msg->u.watch.vec,
789 msg->u.watch.vec_size);
790 kfree(msg->u.watch.vec);
791 kfree(msg);
792 }
794 up(&xenwatch_mutex);
795 }
796 }
798 static int process_msg(void)
799 {
800 struct xs_stored_msg *msg;
801 char *body;
802 int err;
804 msg = kmalloc(sizeof(*msg), GFP_KERNEL);
805 if (msg == NULL)
806 return -ENOMEM;
808 err = xb_read(&msg->hdr, sizeof(msg->hdr));
809 if (err) {
810 kfree(msg);
811 return err;
812 }
814 body = kmalloc(msg->hdr.len + 1, GFP_KERNEL);
815 if (body == NULL) {
816 kfree(msg);
817 return -ENOMEM;
818 }
820 err = xb_read(body, msg->hdr.len);
821 if (err) {
822 kfree(body);
823 kfree(msg);
824 return err;
825 }
826 body[msg->hdr.len] = '\0';
828 if (msg->hdr.type == XS_WATCH_EVENT) {
829 msg->u.watch.vec = split(body, msg->hdr.len,
830 &msg->u.watch.vec_size);
831 if (IS_ERR(msg->u.watch.vec)) {
832 kfree(msg);
833 return PTR_ERR(msg->u.watch.vec);
834 }
836 spin_lock(&watches_lock);
837 msg->u.watch.handle = find_watch(
838 msg->u.watch.vec[XS_WATCH_TOKEN]);
839 if (msg->u.watch.handle != NULL) {
840 spin_lock(&watch_events_lock);
841 list_add_tail(&msg->list, &watch_events);
842 wake_up(&watch_events_waitq);
843 spin_unlock(&watch_events_lock);
844 } else {
845 kfree(msg->u.watch.vec);
846 kfree(msg);
847 }
848 spin_unlock(&watches_lock);
849 } else {
850 msg->u.reply.body = body;
851 spin_lock(&xs_state.reply_lock);
852 list_add_tail(&msg->list, &xs_state.reply_list);
853 spin_unlock(&xs_state.reply_lock);
854 wake_up(&xs_state.reply_waitq);
855 }
857 return 0;
858 }
860 static int xenbus_thread(void *unused)
861 {
862 int err;
864 for (;;) {
865 err = process_msg();
866 if (err)
867 printk(KERN_WARNING "XENBUS error %d while reading "
868 "message\n", err);
869 }
870 }
872 int xs_init(void)
873 {
874 int err;
875 struct task_struct *task;
877 INIT_LIST_HEAD(&xs_state.reply_list);
878 spin_lock_init(&xs_state.reply_lock);
879 init_waitqueue_head(&xs_state.reply_waitq);
881 init_MUTEX(&xs_state.request_mutex);
882 init_rwsem(&xs_state.suspend_mutex);
884 /* Initialize the shared memory rings to talk to xenstored */
885 err = xb_init_comms();
886 if (err)
887 return err;
889 task = kthread_run(xenwatch_thread, NULL, "xenwatch");
890 if (IS_ERR(task))
891 return PTR_ERR(task);
892 xenwatch_pid = task->pid;
894 task = kthread_run(xenbus_thread, NULL, "xenbus");
895 if (IS_ERR(task))
896 return PTR_ERR(task);
898 return 0;
899 }
901 /*
902 * Local variables:
903 * c-file-style: "linux"
904 * indent-tabs-mode: t
905 * c-indent-level: 8
906 * c-basic-offset: 8
907 * tab-width: 8
908 * End:
909 */