0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0035
0036 #define DPRINTK(fmt, ...) \
0037 pr_debug("(%s:%d) " fmt "\n", \
0038 __func__, __LINE__, ##__VA_ARGS__)
0039
0040 #include <linux/kernel.h>
0041 #include <linux/err.h>
0042 #include <linux/string.h>
0043 #include <linux/ctype.h>
0044 #include <linux/fcntl.h>
0045 #include <linux/mm.h>
0046 #include <linux/notifier.h>
0047 #include <linux/export.h>
0048 #include <linux/semaphore.h>
0049
0050 #include <asm/page.h>
0051 #include <asm/xen/hypervisor.h>
0052 #include <asm/hypervisor.h>
0053 #include <xen/xenbus.h>
0054 #include <xen/features.h>
0055
0056 #include "xenbus.h"
0057
0058
0059 static int backend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename)
0060 {
0061 int domid, err;
0062 const char *devid, *type, *frontend;
0063 unsigned int typelen;
0064
0065 type = strchr(nodename, '/');
0066 if (!type)
0067 return -EINVAL;
0068 type++;
0069 typelen = strcspn(type, "/");
0070 if (!typelen || type[typelen] != '/')
0071 return -EINVAL;
0072
0073 devid = strrchr(nodename, '/') + 1;
0074
0075 err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid,
0076 "frontend", NULL, &frontend,
0077 NULL);
0078 if (err)
0079 return err;
0080 if (strlen(frontend) == 0)
0081 err = -ERANGE;
0082 if (!err && !xenbus_exists(XBT_NIL, frontend, ""))
0083 err = -ENOENT;
0084 kfree(frontend);
0085
0086 if (err)
0087 return err;
0088
0089 if (snprintf(bus_id, XEN_BUS_ID_SIZE, "%.*s-%i-%s",
0090 typelen, type, domid, devid) >= XEN_BUS_ID_SIZE)
0091 return -ENOSPC;
0092 return 0;
0093 }
0094
0095 static int xenbus_uevent_backend(struct device *dev,
0096 struct kobj_uevent_env *env)
0097 {
0098 struct xenbus_device *xdev;
0099 struct xenbus_driver *drv;
0100 struct xen_bus_type *bus;
0101
0102 DPRINTK("");
0103
0104 if (dev == NULL)
0105 return -ENODEV;
0106
0107 xdev = to_xenbus_device(dev);
0108 bus = container_of(xdev->dev.bus, struct xen_bus_type, bus);
0109
0110 if (add_uevent_var(env, "MODALIAS=xen-backend:%s", xdev->devicetype))
0111 return -ENOMEM;
0112
0113
0114 if (add_uevent_var(env, "XENBUS_TYPE=%s", xdev->devicetype))
0115 return -ENOMEM;
0116
0117 if (add_uevent_var(env, "XENBUS_PATH=%s", xdev->nodename))
0118 return -ENOMEM;
0119
0120 if (add_uevent_var(env, "XENBUS_BASE_PATH=%s", bus->root))
0121 return -ENOMEM;
0122
0123 if (dev->driver) {
0124 drv = to_xenbus_driver(dev->driver);
0125 if (drv && drv->uevent)
0126 return drv->uevent(xdev, env);
0127 }
0128
0129 return 0;
0130 }
0131
0132
0133 static int xenbus_probe_backend_unit(struct xen_bus_type *bus,
0134 const char *dir,
0135 const char *type,
0136 const char *name)
0137 {
0138 char *nodename;
0139 int err;
0140
0141 nodename = kasprintf(GFP_KERNEL, "%s/%s", dir, name);
0142 if (!nodename)
0143 return -ENOMEM;
0144
0145 DPRINTK("%s\n", nodename);
0146
0147 err = xenbus_probe_node(bus, type, nodename);
0148 kfree(nodename);
0149 return err;
0150 }
0151
0152
0153 static int xenbus_probe_backend(struct xen_bus_type *bus, const char *type,
0154 const char *domid)
0155 {
0156 char *nodename;
0157 int err = 0;
0158 char **dir;
0159 unsigned int i, dir_n = 0;
0160
0161 DPRINTK("");
0162
0163 nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", bus->root, type, domid);
0164 if (!nodename)
0165 return -ENOMEM;
0166
0167 dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n);
0168 if (IS_ERR(dir)) {
0169 kfree(nodename);
0170 return PTR_ERR(dir);
0171 }
0172
0173 for (i = 0; i < dir_n; i++) {
0174 err = xenbus_probe_backend_unit(bus, nodename, type, dir[i]);
0175 if (err)
0176 break;
0177 }
0178 kfree(dir);
0179 kfree(nodename);
0180 return err;
0181 }
0182
0183 static bool frontend_will_handle(struct xenbus_watch *watch,
0184 const char *path, const char *token)
0185 {
0186 return watch->nr_pending == 0;
0187 }
0188
0189 static void frontend_changed(struct xenbus_watch *watch,
0190 const char *path, const char *token)
0191 {
0192 xenbus_otherend_changed(watch, path, token, 0);
0193 }
0194
0195 static struct xen_bus_type xenbus_backend = {
0196 .root = "backend",
0197 .levels = 3,
0198 .get_bus_id = backend_bus_id,
0199 .probe = xenbus_probe_backend,
0200 .otherend_will_handle = frontend_will_handle,
0201 .otherend_changed = frontend_changed,
0202 .bus = {
0203 .name = "xen-backend",
0204 .match = xenbus_match,
0205 .uevent = xenbus_uevent_backend,
0206 .probe = xenbus_dev_probe,
0207 .remove = xenbus_dev_remove,
0208 .dev_groups = xenbus_dev_groups,
0209 },
0210 };
0211
0212 static void backend_changed(struct xenbus_watch *watch,
0213 const char *path, const char *token)
0214 {
0215 DPRINTK("");
0216
0217 xenbus_dev_changed(path, &xenbus_backend);
0218 }
0219
0220 static struct xenbus_watch be_watch = {
0221 .node = "backend",
0222 .callback = backend_changed,
0223 };
0224
0225 static int read_frontend_details(struct xenbus_device *xendev)
0226 {
0227 return xenbus_read_otherend_details(xendev, "frontend-id", "frontend");
0228 }
0229
0230 int xenbus_dev_is_online(struct xenbus_device *dev)
0231 {
0232 return !!xenbus_read_unsigned(dev->nodename, "online", 0);
0233 }
0234 EXPORT_SYMBOL_GPL(xenbus_dev_is_online);
0235
0236 int __xenbus_register_backend(struct xenbus_driver *drv, struct module *owner,
0237 const char *mod_name)
0238 {
0239 drv->read_otherend_details = read_frontend_details;
0240
0241 return xenbus_register_driver_common(drv, &xenbus_backend,
0242 owner, mod_name);
0243 }
0244 EXPORT_SYMBOL_GPL(__xenbus_register_backend);
0245
0246 static int backend_probe_and_watch(struct notifier_block *notifier,
0247 unsigned long event,
0248 void *data)
0249 {
0250
0251 xenbus_probe_devices(&xenbus_backend);
0252 register_xenbus_watch(&be_watch);
0253
0254 return NOTIFY_DONE;
0255 }
0256
0257 static int backend_reclaim_memory(struct device *dev, void *data)
0258 {
0259 const struct xenbus_driver *drv;
0260 struct xenbus_device *xdev;
0261
0262 if (!dev->driver)
0263 return 0;
0264 drv = to_xenbus_driver(dev->driver);
0265 if (drv && drv->reclaim_memory) {
0266 xdev = to_xenbus_device(dev);
0267 if (down_trylock(&xdev->reclaim_sem))
0268 return 0;
0269 drv->reclaim_memory(xdev);
0270 up(&xdev->reclaim_sem);
0271 }
0272 return 0;
0273 }
0274
0275
0276
0277
0278
0279 static unsigned long backend_shrink_memory_count(struct shrinker *shrinker,
0280 struct shrink_control *sc)
0281 {
0282 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL,
0283 backend_reclaim_memory);
0284 return 0;
0285 }
0286
0287 static struct shrinker backend_memory_shrinker = {
0288 .count_objects = backend_shrink_memory_count,
0289 .seeks = DEFAULT_SEEKS,
0290 };
0291
0292 static int __init xenbus_probe_backend_init(void)
0293 {
0294 static struct notifier_block xenstore_notifier = {
0295 .notifier_call = backend_probe_and_watch
0296 };
0297 int err;
0298
0299 DPRINTK("");
0300
0301
0302 err = bus_register(&xenbus_backend.bus);
0303 if (err)
0304 return err;
0305
0306 register_xenstore_notifier(&xenstore_notifier);
0307
0308 if (register_shrinker(&backend_memory_shrinker, "xen-backend"))
0309 pr_warn("shrinker registration failed\n");
0310
0311 return 0;
0312 }
0313 subsys_initcall(xenbus_probe_backend_init);