1 /* drivers/xen/blktap/xenbus.c
3 * Xenbus code for blktap
5 * Copyright (c) 2004-2005, Andrew Warfield and Julian Chesterfield
7 * Based on the blkback xenbus code:
9 * Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
10 * Copyright (C) 2005 XenSource Ltd
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License version 2
14 * as published by the Free Software Foundation; or, when distributed
15 * separately from the Linux kernel or incorporated into other
16 * software packages, subject to the following license:
18 * Permission is hereby granted, free of charge, to any person obtaining a copy
19 * of this source file (the "Software"), to deal in the Software without
20 * restriction, including without limitation the rights to use, copy, modify,
21 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
22 * and to permit persons to whom the Software is furnished to do so, subject to
23 * the following conditions:
25 * The above copyright notice and this permission notice shall be included in
26 * all copies or substantial portions of the Software.
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
38 #include <linux/kthread.h>
39 #include <xen/xenbus.h>
41 #include "../core/domctl.h"
46 struct xenbus_device *dev;
48 struct xenbus_watch backend_watch;
53 static void connect(struct backend_info *);
54 static int connect_ring(struct backend_info *);
55 static int blktap_remove(struct xenbus_device *dev);
56 static int blktap_probe(struct xenbus_device *dev,
57 const struct xenbus_device_id *id);
58 static void tap_backend_changed(struct xenbus_watch *, const char **,
60 static void tap_frontend_changed(struct xenbus_device *dev,
61 enum xenbus_state frontend_state);
63 static int strsep_len(const char *str, char c, unsigned int len)
67 for (i = 0; str[i]; i++)
76 static long get_id(const char *str)
82 len = strsep_len(str, '/', 2);
87 strlcpy(num, ptr, ARRAY_SIZE(num));
88 DPRINTK("get_id(%s) -> %s\n", str, num);
90 return simple_strtol(num, NULL, 10);
93 static int blktap_name(blkif_t *blkif, char *buf)
95 char *devpath, *devname;
96 struct xenbus_device *dev = blkif->be->dev;
98 devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL);
100 return PTR_ERR(devpath);
102 if ((devname = strstr(devpath, "/dev/")) != NULL)
103 devname += strlen("/dev/");
107 snprintf(buf, TASK_COMM_LEN, "blktap.%d.%s", blkif->domid, devname);
113 /****************************************************************
114 * sysfs interface for I/O requests of blktap device
117 #define VBD_SHOW(name, format, args...) \
118 static ssize_t show_##name(struct device *_dev, \
119 struct device_attribute *attr, \
122 ssize_t ret = -ENODEV; \
123 struct xenbus_device *dev; \
124 struct backend_info *be; \
126 if (!get_device(_dev)) \
128 dev = to_xenbus_device(_dev); \
129 if ((be = dev_get_drvdata(&dev->dev)) != NULL) \
130 ret = sprintf(buf, format, ##args); \
134 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
136 VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
137 VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
138 VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
139 VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect);
140 VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect);
142 static struct attribute *tapstat_attrs[] = {
143 &dev_attr_oo_req.attr,
144 &dev_attr_rd_req.attr,
145 &dev_attr_wr_req.attr,
146 &dev_attr_rd_sect.attr,
147 &dev_attr_wr_sect.attr,
151 static const struct attribute_group tapstat_group = {
152 .name = "statistics",
153 .attrs = tapstat_attrs,
156 int xentap_sysfs_addif(struct xenbus_device *dev)
159 struct backend_info *be = dev_get_drvdata(&dev->dev);
160 err = sysfs_create_group(&dev->dev.kobj, &tapstat_group);
166 void xentap_sysfs_delif(struct xenbus_device *dev)
168 struct backend_info *be = dev_get_drvdata(&dev->dev);
169 sysfs_remove_group(&dev->dev.kobj, &tapstat_group);
173 static int blktap_remove(struct xenbus_device *dev)
175 struct backend_info *be = dev_get_drvdata(&dev->dev);
178 xentap_sysfs_delif(be->dev);
179 if (be->backend_watch.node) {
180 unregister_xenbus_watch(&be->backend_watch);
181 kfree(be->backend_watch.node);
182 be->backend_watch.node = NULL;
185 if (be->blkif->xenblkd)
186 kthread_stop(be->blkif->xenblkd);
187 signal_tapdisk(be->blkif->dev_num);
188 tap_blkif_free(be->blkif, dev);
189 tap_blkif_kmem_cache_free(be->blkif);
193 dev_set_drvdata(&dev->dev, NULL);
197 static void tap_update_blkif_status(blkif_t *blkif)
200 char name[TASK_COMM_LEN];
202 /* Not ready to connect? */
203 if(!blkif->irq || !blkif->sectors) {
207 /* Already connected? */
208 if (blkif->be->dev->state == XenbusStateConnected)
211 /* Attempt to connect: exit if we fail to. */
213 if (blkif->be->dev->state != XenbusStateConnected)
216 err = blktap_name(blkif, name);
218 xenbus_dev_error(blkif->be->dev, err, "get blktap dev name");
222 if (!blkif->be->group_added) {
223 err = xentap_sysfs_addif(blkif->be->dev);
225 xenbus_dev_fatal(blkif->be->dev, err,
226 "creating sysfs entries");
231 blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif, name);
232 if (IS_ERR(blkif->xenblkd)) {
233 err = PTR_ERR(blkif->xenblkd);
234 blkif->xenblkd = NULL;
235 xenbus_dev_fatal(blkif->be->dev, err, "start xenblkd");
236 WPRINTK("Error starting thread %s\n", name);
238 DPRINTK("Thread started for domid %d, connected disk %d\n",
239 blkif->domid, blkif->dev_num);
244 * Entry point to this code when a new device is created. Allocate
245 * the basic structures, and watch the store waiting for the
246 * user-space program to tell us the physical device info. Switch to
249 static int blktap_probe(struct xenbus_device *dev,
250 const struct xenbus_device_id *id)
253 struct backend_info *be = kzalloc(sizeof(struct backend_info),
256 xenbus_dev_fatal(dev, -ENOMEM,
257 "allocating backend structure");
262 dev_set_drvdata(&dev->dev, be);
263 be->xenbus_id = get_id(dev->nodename);
265 be->blkif = tap_alloc_blkif(dev->otherend_id);
266 if (IS_ERR(be->blkif)) {
267 err = PTR_ERR(be->blkif);
269 xenbus_dev_fatal(dev, err, "creating block interface");
273 /* setup back pointer */
275 be->blkif->sectors = 0;
277 /* set a watch on disk info, waiting for userspace to update details*/
278 err = xenbus_watch_path2(dev, dev->nodename, "info",
279 &be->backend_watch, tap_backend_changed);
283 err = xenbus_switch_state(dev, XenbusStateInitWait);
289 DPRINTK("blktap probe failed\n");
296 * Callback received when the user space code has placed the device
297 * information in xenstore.
299 static void tap_backend_changed(struct xenbus_watch *watch,
300 const char **vec, unsigned int len)
304 struct backend_info *be
305 = container_of(watch, struct backend_info, backend_watch);
306 struct xenbus_device *dev = be->dev;
309 * Check to see whether userspace code has opened the image
311 * and disk info to xenstore
313 err = xenbus_gather(XBT_NIL, dev->nodename, "info", "%lu", &info,
314 "sectors", "%Lu", &be->blkif->sectors, NULL);
315 if (XENBUS_EXIST_ERR(err))
318 xenbus_dev_error(dev, err, "getting info");
322 DPRINTK("Userspace update on disk info, %lu\n",info);
324 /* Associate tap dev with domid*/
325 be->blkif->dev_num = dom_to_devid(be->blkif->domid, be->xenbus_id,
328 tap_update_blkif_status(be->blkif);
332 static void blkif_disconnect(blkif_t *blkif)
334 if (blkif->xenblkd) {
335 kthread_stop(blkif->xenblkd);
336 blkif->xenblkd = NULL;
340 tap_blkif_free(blkif, blkif->be->dev);
344 * Callback received when the frontend's state changes.
346 static void tap_frontend_changed(struct xenbus_device *dev,
347 enum xenbus_state frontend_state)
349 struct backend_info *be = dev_get_drvdata(&dev->dev);
352 DPRINTK("fe_changed(%s,%d)\n", dev->nodename, frontend_state);
354 switch (frontend_state) {
355 case XenbusStateInitialising:
356 if (dev->state == XenbusStateClosed) {
357 pr_info("%s: %s: prepare for reconnect\n",
358 __FUNCTION__, dev->nodename);
359 xenbus_switch_state(dev, XenbusStateInitWait);
363 case XenbusStateInitialised:
364 case XenbusStateConnected:
365 /* Ensure we connect even when two watches fire in
366 close successsion and we miss the intermediate value
367 of frontend_state. */
368 if (dev->state == XenbusStateConnected)
371 /* Enforce precondition before potential leak point.
372 * blkif_disconnect() is idempotent.
374 blkif_disconnect(be->blkif);
376 err = connect_ring(be);
379 tap_update_blkif_status(be->blkif);
382 case XenbusStateClosing:
383 blkif_disconnect(be->blkif);
384 xenbus_switch_state(dev, XenbusStateClosing);
387 case XenbusStateClosed:
388 xenbus_switch_state(dev, XenbusStateClosed);
389 if (xenbus_dev_is_online(dev))
391 /* fall through if not online */
392 case XenbusStateUnknown:
393 /* Implies the effects of blkif_disconnect() via
396 device_unregister(&dev->dev);
400 xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
408 * Switch to Connected state.
410 static void connect(struct backend_info *be)
414 struct xenbus_device *dev = be->dev;
415 struct xenbus_transaction xbt;
417 /* Write feature-barrier to xenstore */
419 err = xenbus_transaction_start(&xbt);
421 xenbus_dev_fatal(dev, err, "starting transaction");
425 err = xenbus_printf(xbt, dev->nodename, "feature-barrier", "1");
427 xenbus_dev_fatal(dev, err, "writing feature-barrier");
428 xenbus_transaction_end(xbt, 1);
432 err = xenbus_transaction_end(xbt, 0);
437 err = xenbus_switch_state(dev, XenbusStateConnected);
439 xenbus_dev_fatal(dev, err, "%s: switching to Connected state",
446 static int connect_ring(struct backend_info *be)
448 struct xenbus_device *dev = be->dev;
449 unsigned int ring_ref, evtchn;
453 DPRINTK("%s\n", dev->otherend);
455 err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%u",
456 &ring_ref, "event-channel", "%u", &evtchn, NULL);
458 xenbus_dev_fatal(dev, err,
459 "reading %s/ring-ref and event-channel",
464 be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE;
465 err = xenbus_gather(XBT_NIL, dev->otherend, "protocol",
466 NULL, &protocol, NULL);
469 be->blkif->blk_protocol = xen_guest_blkif_protocol(be->blkif->domid);
471 else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE))
472 be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE;
473 else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32))
474 be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_32;
475 else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_64))
476 be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_64;
478 xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol);
482 pr_info("blktap: ring-ref %u, event-channel %u, protocol %d (%s)\n",
483 ring_ref, evtchn, be->blkif->blk_protocol,
484 protocol ?: "unspecified");
487 /* Map the shared frame, irq etc. */
488 err = tap_blkif_map(be->blkif, dev, ring_ref, evtchn);
490 xenbus_dev_fatal(dev, err, "mapping ring-ref %u port %u",
499 /* ** Driver Registration ** */
502 static const struct xenbus_device_id blktap_ids[] = {
507 static DEFINE_XENBUS_DRIVER(blktap, ,
508 .probe = blktap_probe,
509 .remove = blktap_remove,
510 .otherend_changed = tap_frontend_changed
514 void tap_blkif_xenbus_init(void)
516 WARN_ON(xenbus_register_backend(&blktap_driver));