/[pkg-src]/tags/kernel26-xen-2_6_25_r1-fedora9-patches/kernel26-xen/patches-2.6.25-r1/1014-2.6.25-xen-Add-proc-xen-xenbus.patch |
Annotation of /tags/kernel26-xen-2_6_25_r1-fedora9-patches/kernel26-xen/patches-2.6.25-r1/1014-2.6.25-xen-Add-proc-xen-xenbus.patch
Parent Directory
|
Revision Log
Revision 608 -
(hide annotations)
(download)
Fri May 23 12:17:32 2008 UTC (16 years, 1 month ago) by (unknown author)
File size: 14237 byte(s)
Fri May 23 12:17:32 2008 UTC (16 years, 1 month ago) by (unknown author)
File size: 14237 byte(s)
This commit was manufactured by cvs2svn to create tag 'kernel26-xen-2_6_25_r1-fedora9-patches'.
1 | niro | 606 | From 8b4585c4677d8e9e58a1e156b113494abd74c541 Mon Sep 17 00:00:00 2001 |
2 | From: Mark McLoughlin <markmc@redhat.com> | ||
3 | Date: Mon, 4 Feb 2008 22:04:36 +0000 | ||
4 | Subject: [PATCH] xen: Add /proc/xen/xenbus | ||
5 | |||
6 | This interface is used by userspace programs to talk to | ||
7 | xenstored. | ||
8 | |||
9 | Since xenstored makes itself available to Dom0 userspace | ||
10 | via a socket this should only really be useful in Domu, | ||
11 | but it turns out that Dom0 apps historically default | ||
12 | to using /proc/xen/xenbus rather than the socket. | ||
13 | |||
14 | Signed-off-by: Mark McLoughlin <markmc@redhat.com> | ||
15 | --- | ||
16 | drivers/xen/xenbus/xenbus_comms.h | 1 - | ||
17 | drivers/xen/xenbus/xenbus_probe.c | 2 + | ||
18 | drivers/xen/xenbus/xenbus_xs.c | 1 + | ||
19 | drivers/xen/xenctrl/Makefile | 1 + | ||
20 | drivers/xen/xenctrl/main.c | 6 + | ||
21 | drivers/xen/xenctrl/xenbus.c | 398 +++++++++++++++++++++++++++++++++++++ | ||
22 | drivers/xen/xenctrl/xenctrl.h | 6 + | ||
23 | include/xen/xenbus.h | 2 + | ||
24 | 8 files changed, 416 insertions(+), 1 deletions(-) | ||
25 | create mode 100644 drivers/xen/xenctrl/xenbus.c | ||
26 | |||
27 | diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h | ||
28 | index c21db75..fcc9b29 100644 | ||
29 | --- a/drivers/xen/xenbus/xenbus_comms.h | ||
30 | +++ b/drivers/xen/xenbus/xenbus_comms.h | ||
31 | @@ -41,6 +41,5 @@ int xb_data_to_read(void); | ||
32 | int xb_wait_for_data_to_read(void); | ||
33 | int xs_input_avail(void); | ||
34 | extern struct xenstore_domain_interface *xen_store_interface; | ||
35 | -extern int xen_store_evtchn; | ||
36 | |||
37 | #endif /* _XENBUS_COMMS_H */ | ||
38 | diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c | ||
39 | index 57ceb53..c811581 100644 | ||
40 | --- a/drivers/xen/xenbus/xenbus_probe.c | ||
41 | +++ b/drivers/xen/xenbus/xenbus_probe.c | ||
42 | @@ -56,6 +56,8 @@ | ||
43 | #include "xenbus_probe.h" | ||
44 | |||
45 | int xen_store_evtchn; | ||
46 | +EXPORT_SYMBOL_GPL(xen_store_evtchn); | ||
47 | + | ||
48 | struct xenstore_domain_interface *xen_store_interface; | ||
49 | static unsigned long xen_store_mfn; | ||
50 | |||
51 | diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c | ||
52 | index 227d53b..810e24a 100644 | ||
53 | --- a/drivers/xen/xenbus/xenbus_xs.c | ||
54 | +++ b/drivers/xen/xenbus/xenbus_xs.c | ||
55 | @@ -184,6 +184,7 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg) | ||
56 | |||
57 | return ret; | ||
58 | } | ||
59 | +EXPORT_SYMBOL(xenbus_dev_request_and_reply); | ||
60 | |||
61 | /* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */ | ||
62 | static void *xs_talkv(struct xenbus_transaction t, | ||
63 | diff --git a/drivers/xen/xenctrl/Makefile b/drivers/xen/xenctrl/Makefile | ||
64 | index 8a706cb..23dafa3 100644 | ||
65 | --- a/drivers/xen/xenctrl/Makefile | ||
66 | +++ b/drivers/xen/xenctrl/Makefile | ||
67 | @@ -4,3 +4,4 @@ xenctrl-objs = | ||
68 | xenctrl-objs += main.o | ||
69 | xenctrl-objs += capabilities.o | ||
70 | xenctrl-objs += privcmd.o | ||
71 | +xenctrl-objs += xenbus.o | ||
72 | diff --git a/drivers/xen/xenctrl/main.c b/drivers/xen/xenctrl/main.c | ||
73 | index d1fe6ef..b0cf61b 100644 | ||
74 | --- a/drivers/xen/xenctrl/main.c | ||
75 | +++ b/drivers/xen/xenctrl/main.c | ||
76 | @@ -59,8 +59,13 @@ static int __init xenctrl_init(void) | ||
77 | if (ret) | ||
78 | goto fail2; | ||
79 | |||
80 | + ret = xenbus_create_proc_entry(); | ||
81 | + if (ret) | ||
82 | + goto fail3; | ||
83 | + | ||
84 | return 0; | ||
85 | |||
86 | + fail3: privcmd_remove_proc_entry(); | ||
87 | fail2: capabilities_remove_proc_entry(); | ||
88 | fail1: remove_proc_entry("xen", NULL); | ||
89 | return ret; | ||
90 | @@ -68,6 +73,7 @@ static int __init xenctrl_init(void) | ||
91 | |||
92 | static void __exit xenctrl_exit(void) | ||
93 | { | ||
94 | + xenbus_remove_proc_entry(); | ||
95 | privcmd_remove_proc_entry(); | ||
96 | capabilities_remove_proc_entry(); | ||
97 | remove_proc_entry("xen", NULL); | ||
98 | diff --git a/drivers/xen/xenctrl/xenbus.c b/drivers/xen/xenctrl/xenbus.c | ||
99 | new file mode 100644 | ||
100 | index 0000000..57d5501 | ||
101 | --- /dev/null | ||
102 | +++ b/drivers/xen/xenctrl/xenbus.c | ||
103 | @@ -0,0 +1,398 @@ | ||
104 | +/* | ||
105 | + * xenbus.c | ||
106 | + * | ||
107 | + * /proc/xen/xenbus gives user-space access to the kernel's xenbus | ||
108 | + * connection to xenstore. | ||
109 | + * | ||
110 | + * Copyright (c) 2005, Christian Limpach | ||
111 | + * Copyright (c) 2005, Rusty Russell, IBM Corporation | ||
112 | + * | ||
113 | + * This program is free software; you can redistribute it and/or | ||
114 | + * modify it under the terms of the GNU General Public License version 2 | ||
115 | + * as published by the Free Software Foundation; or, when distributed | ||
116 | + * separately from the Linux kernel or incorporated into other | ||
117 | + * software packages, subject to the following license: | ||
118 | + * | ||
119 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
120 | + * of this source file (the "Software"), to deal in the Software without | ||
121 | + * restriction, including without limitation the rights to use, copy, modify, | ||
122 | + * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
123 | + * and to permit persons to whom the Software is furnished to do so, subject to | ||
124 | + * the following conditions: | ||
125 | + * | ||
126 | + * The above copyright notice and this permission notice shall be included in | ||
127 | + * all copies or substantial portions of the Software. | ||
128 | + * | ||
129 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
130 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
131 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
132 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
133 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
134 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
135 | + * IN THE SOFTWARE. | ||
136 | + */ | ||
137 | + | ||
138 | +#include <linux/proc_fs.h> | ||
139 | +#include <linux/module.h> | ||
140 | +#include <linux/uaccess.h> | ||
141 | +#include <linux/poll.h> | ||
142 | + | ||
143 | +#include <xen/xenbus.h> | ||
144 | + | ||
145 | +struct xenbus_dev_transaction { | ||
146 | + struct list_head list; | ||
147 | + struct xenbus_transaction handle; | ||
148 | +}; | ||
149 | + | ||
150 | +struct read_buffer { | ||
151 | + struct list_head list; | ||
152 | + unsigned int cons; | ||
153 | + unsigned int len; | ||
154 | + char msg[]; | ||
155 | +}; | ||
156 | + | ||
157 | +struct xenbus_dev_data { | ||
158 | + /* In-progress transaction. */ | ||
159 | + struct list_head transactions; | ||
160 | + | ||
161 | + /* Active watches. */ | ||
162 | + struct list_head watches; | ||
163 | + | ||
164 | + /* Partial request. */ | ||
165 | + unsigned int len; | ||
166 | + union { | ||
167 | + struct xsd_sockmsg msg; | ||
168 | + char buffer[PAGE_SIZE]; | ||
169 | + } u; | ||
170 | + | ||
171 | + /* Response queue. */ | ||
172 | + struct list_head read_buffers; | ||
173 | + wait_queue_head_t read_waitq; | ||
174 | + | ||
175 | + struct mutex reply_mutex; | ||
176 | +}; | ||
177 | + | ||
178 | +static ssize_t xenbus_dev_read(struct file *filp, | ||
179 | + char __user *ubuf, | ||
180 | + size_t len, loff_t *ppos) | ||
181 | +{ | ||
182 | + struct xenbus_dev_data *u = filp->private_data; | ||
183 | + struct read_buffer *rb; | ||
184 | + int i, ret; | ||
185 | + | ||
186 | + mutex_lock(&u->reply_mutex); | ||
187 | + while (list_empty(&u->read_buffers)) { | ||
188 | + mutex_unlock(&u->reply_mutex); | ||
189 | + ret = wait_event_interruptible(u->read_waitq, | ||
190 | + !list_empty(&u->read_buffers)); | ||
191 | + if (ret) | ||
192 | + return ret; | ||
193 | + mutex_lock(&u->reply_mutex); | ||
194 | + } | ||
195 | + | ||
196 | + rb = list_entry(u->read_buffers.next, struct read_buffer, list); | ||
197 | + for (i = 0; i < len;) { | ||
198 | + put_user(rb->msg[rb->cons], ubuf + i); | ||
199 | + i++; | ||
200 | + rb->cons++; | ||
201 | + if (rb->cons == rb->len) { | ||
202 | + list_del(&rb->list); | ||
203 | + kfree(rb); | ||
204 | + if (list_empty(&u->read_buffers)) | ||
205 | + break; | ||
206 | + rb = list_entry(u->read_buffers.next, | ||
207 | + struct read_buffer, list); | ||
208 | + } | ||
209 | + } | ||
210 | + mutex_unlock(&u->reply_mutex); | ||
211 | + | ||
212 | + return i; | ||
213 | +} | ||
214 | + | ||
215 | +static void queue_reply(struct xenbus_dev_data *u, | ||
216 | + char *data, unsigned int len) | ||
217 | +{ | ||
218 | + struct read_buffer *rb; | ||
219 | + | ||
220 | + if (len == 0) | ||
221 | + return; | ||
222 | + | ||
223 | + rb = kmalloc(sizeof(*rb) + len, GFP_KERNEL); | ||
224 | + BUG_ON(rb == NULL); | ||
225 | + | ||
226 | + rb->cons = 0; | ||
227 | + rb->len = len; | ||
228 | + | ||
229 | + memcpy(rb->msg, data, len); | ||
230 | + | ||
231 | + list_add_tail(&rb->list, &u->read_buffers); | ||
232 | + | ||
233 | + wake_up(&u->read_waitq); | ||
234 | +} | ||
235 | + | ||
236 | +struct watch_adapter | ||
237 | +{ | ||
238 | + struct list_head list; | ||
239 | + struct xenbus_watch watch; | ||
240 | + struct xenbus_dev_data *dev_data; | ||
241 | + char *token; | ||
242 | +}; | ||
243 | + | ||
244 | +static void free_watch_adapter(struct watch_adapter *watch) | ||
245 | +{ | ||
246 | + kfree(watch->watch.node); | ||
247 | + kfree(watch->token); | ||
248 | + kfree(watch); | ||
249 | +} | ||
250 | + | ||
251 | +static void watch_fired(struct xenbus_watch *watch, | ||
252 | + const char **vec, | ||
253 | + unsigned int len) | ||
254 | +{ | ||
255 | + struct watch_adapter *adap = | ||
256 | + container_of(watch, struct watch_adapter, watch); | ||
257 | + struct xsd_sockmsg hdr; | ||
258 | + const char *path, *token; | ||
259 | + int path_len, tok_len, body_len; | ||
260 | + | ||
261 | + path = vec[XS_WATCH_PATH]; | ||
262 | + token = adap->token; | ||
263 | + | ||
264 | + path_len = strlen(path) + 1; | ||
265 | + tok_len = strlen(token) + 1; | ||
266 | + body_len = path_len + tok_len; | ||
267 | + | ||
268 | + hdr.type = XS_WATCH_EVENT; | ||
269 | + hdr.len = body_len; | ||
270 | + | ||
271 | + mutex_lock(&adap->dev_data->reply_mutex); | ||
272 | + queue_reply(adap->dev_data, (char *)&hdr, sizeof(hdr)); | ||
273 | + queue_reply(adap->dev_data, (char *)path, path_len); | ||
274 | + queue_reply(adap->dev_data, (char *)token, tok_len); | ||
275 | + mutex_unlock(&adap->dev_data->reply_mutex); | ||
276 | +} | ||
277 | + | ||
278 | +static LIST_HEAD(watch_list); | ||
279 | + | ||
280 | +static ssize_t xenbus_dev_write(struct file *filp, | ||
281 | + const char __user *ubuf, | ||
282 | + size_t len, loff_t *ppos) | ||
283 | +{ | ||
284 | + struct xenbus_dev_data *u = filp->private_data; | ||
285 | + struct xenbus_dev_transaction *trans = NULL; | ||
286 | + uint32_t msg_type; | ||
287 | + void *reply; | ||
288 | + char *path, *token; | ||
289 | + struct watch_adapter *watch, *tmp_watch; | ||
290 | + int err, rc = len; | ||
291 | + | ||
292 | + if ((len + u->len) > sizeof(u->u.buffer)) { | ||
293 | + rc = -EINVAL; | ||
294 | + goto out; | ||
295 | + } | ||
296 | + | ||
297 | + if (copy_from_user(u->u.buffer + u->len, ubuf, len) != 0) { | ||
298 | + rc = -EFAULT; | ||
299 | + goto out; | ||
300 | + } | ||
301 | + | ||
302 | + u->len += len; | ||
303 | + if ((u->len < sizeof(u->u.msg)) || | ||
304 | + (u->len < (sizeof(u->u.msg) + u->u.msg.len))) | ||
305 | + return rc; | ||
306 | + | ||
307 | + msg_type = u->u.msg.type; | ||
308 | + | ||
309 | + switch (msg_type) { | ||
310 | + case XS_TRANSACTION_START: | ||
311 | + case XS_TRANSACTION_END: | ||
312 | + case XS_DIRECTORY: | ||
313 | + case XS_READ: | ||
314 | + case XS_GET_PERMS: | ||
315 | + case XS_RELEASE: | ||
316 | + case XS_GET_DOMAIN_PATH: | ||
317 | + case XS_WRITE: | ||
318 | + case XS_MKDIR: | ||
319 | + case XS_RM: | ||
320 | + case XS_SET_PERMS: | ||
321 | + if (msg_type == XS_TRANSACTION_START) { | ||
322 | + trans = kmalloc(sizeof(*trans), GFP_KERNEL); | ||
323 | + if (!trans) { | ||
324 | + rc = -ENOMEM; | ||
325 | + goto out; | ||
326 | + } | ||
327 | + } | ||
328 | + | ||
329 | + reply = xenbus_dev_request_and_reply(&u->u.msg); | ||
330 | + if (IS_ERR(reply)) { | ||
331 | + kfree(trans); | ||
332 | + rc = PTR_ERR(reply); | ||
333 | + goto out; | ||
334 | + } | ||
335 | + | ||
336 | + if (msg_type == XS_TRANSACTION_START) { | ||
337 | + trans->handle.id = simple_strtoul(reply, NULL, 0); | ||
338 | + list_add(&trans->list, &u->transactions); | ||
339 | + } else if (msg_type == XS_TRANSACTION_END) { | ||
340 | + list_for_each_entry(trans, &u->transactions, list) | ||
341 | + if (trans->handle.id == u->u.msg.tx_id) | ||
342 | + break; | ||
343 | + BUG_ON(&trans->list == &u->transactions); | ||
344 | + list_del(&trans->list); | ||
345 | + kfree(trans); | ||
346 | + } | ||
347 | + mutex_lock(&u->reply_mutex); | ||
348 | + queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg)); | ||
349 | + queue_reply(u, (char *)reply, u->u.msg.len); | ||
350 | + mutex_unlock(&u->reply_mutex); | ||
351 | + kfree(reply); | ||
352 | + break; | ||
353 | + | ||
354 | + case XS_WATCH: | ||
355 | + case XS_UNWATCH: { | ||
356 | + static const char *XS_RESP = "OK"; | ||
357 | + struct xsd_sockmsg hdr; | ||
358 | + | ||
359 | + path = u->u.buffer + sizeof(u->u.msg); | ||
360 | + token = memchr(path, 0, u->u.msg.len); | ||
361 | + if (token == NULL) { | ||
362 | + rc = -EILSEQ; | ||
363 | + goto out; | ||
364 | + } | ||
365 | + token++; | ||
366 | + | ||
367 | + if (msg_type == XS_WATCH) { | ||
368 | + watch = kmalloc(sizeof(*watch), GFP_KERNEL); | ||
369 | + watch->watch.node = kmalloc(strlen(path)+1, | ||
370 | + GFP_KERNEL); | ||
371 | + strcpy((char *)watch->watch.node, path); | ||
372 | + watch->watch.callback = watch_fired; | ||
373 | + watch->token = kmalloc(strlen(token)+1, GFP_KERNEL); | ||
374 | + strcpy(watch->token, token); | ||
375 | + watch->dev_data = u; | ||
376 | + | ||
377 | + err = register_xenbus_watch(&watch->watch); | ||
378 | + if (err) { | ||
379 | + free_watch_adapter(watch); | ||
380 | + rc = err; | ||
381 | + goto out; | ||
382 | + } | ||
383 | + | ||
384 | + list_add(&watch->list, &u->watches); | ||
385 | + } else { | ||
386 | + list_for_each_entry_safe(watch, tmp_watch, | ||
387 | + &u->watches, list) { | ||
388 | + if (!strcmp(watch->token, token) && | ||
389 | + !strcmp(watch->watch.node, path)) | ||
390 | + { | ||
391 | + unregister_xenbus_watch(&watch->watch); | ||
392 | + list_del(&watch->list); | ||
393 | + free_watch_adapter(watch); | ||
394 | + break; | ||
395 | + } | ||
396 | + } | ||
397 | + } | ||
398 | + | ||
399 | + hdr.type = msg_type; | ||
400 | + hdr.len = strlen(XS_RESP) + 1; | ||
401 | + mutex_lock(&u->reply_mutex); | ||
402 | + queue_reply(u, (char *)&hdr, sizeof(hdr)); | ||
403 | + queue_reply(u, (char *)XS_RESP, hdr.len); | ||
404 | + mutex_unlock(&u->reply_mutex); | ||
405 | + break; | ||
406 | + } | ||
407 | + | ||
408 | + default: | ||
409 | + rc = -EINVAL; | ||
410 | + break; | ||
411 | + } | ||
412 | + | ||
413 | + out: | ||
414 | + u->len = 0; | ||
415 | + return rc; | ||
416 | +} | ||
417 | + | ||
418 | +static int xenbus_dev_open(struct inode *inode, struct file *filp) | ||
419 | +{ | ||
420 | + struct xenbus_dev_data *u; | ||
421 | + | ||
422 | + if (xen_store_evtchn == 0) | ||
423 | + return -ENOENT; | ||
424 | + | ||
425 | + nonseekable_open(inode, filp); | ||
426 | + | ||
427 | + u = kzalloc(sizeof(*u), GFP_KERNEL); | ||
428 | + if (u == NULL) | ||
429 | + return -ENOMEM; | ||
430 | + | ||
431 | + INIT_LIST_HEAD(&u->transactions); | ||
432 | + INIT_LIST_HEAD(&u->watches); | ||
433 | + INIT_LIST_HEAD(&u->read_buffers); | ||
434 | + init_waitqueue_head(&u->read_waitq); | ||
435 | + | ||
436 | + mutex_init(&u->reply_mutex); | ||
437 | + | ||
438 | + filp->private_data = u; | ||
439 | + | ||
440 | + return 0; | ||
441 | +} | ||
442 | + | ||
443 | +static int xenbus_dev_release(struct inode *inode, struct file *filp) | ||
444 | +{ | ||
445 | + struct xenbus_dev_data *u = filp->private_data; | ||
446 | + struct xenbus_dev_transaction *trans, *tmp; | ||
447 | + struct watch_adapter *watch, *tmp_watch; | ||
448 | + | ||
449 | + list_for_each_entry_safe(trans, tmp, &u->transactions, list) { | ||
450 | + xenbus_transaction_end(trans->handle, 1); | ||
451 | + list_del(&trans->list); | ||
452 | + kfree(trans); | ||
453 | + } | ||
454 | + | ||
455 | + list_for_each_entry_safe(watch, tmp_watch, &u->watches, list) { | ||
456 | + unregister_xenbus_watch(&watch->watch); | ||
457 | + list_del(&watch->list); | ||
458 | + free_watch_adapter(watch); | ||
459 | + } | ||
460 | + | ||
461 | + kfree(u); | ||
462 | + | ||
463 | + return 0; | ||
464 | +} | ||
465 | + | ||
466 | +static unsigned int xenbus_dev_poll(struct file *file, poll_table *wait) | ||
467 | +{ | ||
468 | + struct xenbus_dev_data *u = file->private_data; | ||
469 | + | ||
470 | + poll_wait(file, &u->read_waitq, wait); | ||
471 | + if (!list_empty(&u->read_buffers)) | ||
472 | + return POLLIN | POLLRDNORM; | ||
473 | + return 0; | ||
474 | +} | ||
475 | + | ||
476 | +static const struct file_operations xenbus_dev_file_ops = { | ||
477 | + .read = xenbus_dev_read, | ||
478 | + .write = xenbus_dev_write, | ||
479 | + .open = xenbus_dev_open, | ||
480 | + .release = xenbus_dev_release, | ||
481 | + .poll = xenbus_dev_poll, | ||
482 | +}; | ||
483 | + | ||
484 | +int __init xenbus_create_proc_entry(void) | ||
485 | +{ | ||
486 | + struct proc_dir_entry *entry; | ||
487 | + | ||
488 | + entry = create_proc_entry("xen/xenbus", 0400, NULL); | ||
489 | + if (!entry) | ||
490 | + return -ENOMEM; | ||
491 | + | ||
492 | + entry->owner = THIS_MODULE; | ||
493 | + entry->proc_fops = &xenbus_dev_file_ops; | ||
494 | + | ||
495 | + return 0; | ||
496 | +} | ||
497 | + | ||
498 | +void __exit xenbus_remove_proc_entry(void) | ||
499 | +{ | ||
500 | + remove_proc_entry("xen/xenbus", NULL); | ||
501 | +} | ||
502 | diff --git a/drivers/xen/xenctrl/xenctrl.h b/drivers/xen/xenctrl/xenctrl.h | ||
503 | index a35209a..e585c4b 100644 | ||
504 | --- a/drivers/xen/xenctrl/xenctrl.h | ||
505 | +++ b/drivers/xen/xenctrl/xenctrl.h | ||
506 | @@ -43,3 +43,9 @@ void capabilities_remove_proc_entry(void) __exit; | ||
507 | */ | ||
508 | int privcmd_create_proc_entry(void) __init; | ||
509 | void privcmd_remove_proc_entry(void) __exit; | ||
510 | + | ||
511 | +/* | ||
512 | + * xenbus.c | ||
513 | + */ | ||
514 | +int xenbus_create_proc_entry(void) __init; | ||
515 | +void xenbus_remove_proc_entry(void) __exit; | ||
516 | diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h | ||
517 | index 6369d89..a3fef9d 100644 | ||
518 | --- a/include/xen/xenbus.h | ||
519 | +++ b/include/xen/xenbus.h | ||
520 | @@ -232,4 +232,6 @@ const char *xenbus_strstate(enum xenbus_state state); | ||
521 | int xenbus_dev_is_online(struct xenbus_device *dev); | ||
522 | int xenbus_frontend_closed(struct xenbus_device *dev); | ||
523 | |||
524 | +extern int xen_store_evtchn; | ||
525 | + | ||
526 | #endif /* _XEN_XENBUS_H */ | ||
527 | -- | ||
528 | 1.5.4.1 | ||
529 |