= container_of(watch, struct backend_info, watch);
/* If other end is gone, delete ourself. */
- if (!xenbus_exists(be->frontpath, "")) {
+ if (node && !xenbus_exists(be->frontpath, "")) {
xenbus_rm(be->dev->nodename, "");
device_unregister(&be->dev->dev);
return;
{
int err;
char *p;
- char *frontend;
long int handle, pdev;
struct backend_info *be
= container_of(watch, struct backend_info, backend_watch);
struct xenbus_device *dev = be->dev;
- frontend = NULL;
- err = xenbus_gather(dev->nodename,
- "frontend-id", "%li", &be->frontend_id,
- "frontend", NULL, &frontend,
- NULL);
- if (XENBUS_EXIST_ERR(err) ||
- strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
- /* If we can't get a frontend path and a frontend-id,
- * then our bus-id is no longer valid and we need to
- * destroy the backend device.
- */
- goto device_fail;
- }
- if (err < 0) {
- xenbus_dev_error(dev, err,
- "reading %s/frontend or frontend-id",
- dev->nodename);
- goto device_fail;
- }
-
- if (!be->frontpath || strcmp(frontend, be->frontpath)) {
- if (be->watch.node)
- unregister_xenbus_watch(&be->watch);
- if (be->frontpath)
- kfree(be->frontpath);
- be->frontpath = frontend;
- frontend = NULL;
- be->watch.node = be->frontpath;
- be->watch.callback = frontend_changed;
- err = register_xenbus_watch(&be->watch);
- if (err) {
- be->watch.node = NULL;
- xenbus_dev_error(dev, err,
- "adding frontend watch on %s",
- be->frontpath);
- goto device_fail;
- }
- }
-
err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev);
if (XENBUS_EXIST_ERR(err))
- goto out;
+ return;
if (err < 0) {
xenbus_dev_error(dev, err, "reading physical-device");
- goto device_fail;
+ return;
}
if (be->pdev && be->pdev != pdev) {
printk(KERN_WARNING
"changing physical-device not supported\n");
- goto device_fail;
+ return;
}
be->pdev = pdev;
err = PTR_ERR(be->blkif);
be->blkif = NULL;
xenbus_dev_error(dev, err, "creating block interface");
- goto device_fail;
+ return;
}
err = vbd_create(be->blkif, handle, be->pdev, be->readonly);
if (err) {
xenbus_dev_error(dev, err, "creating vbd structure");
- goto device_fail;
+ return;
}
- frontend_changed(&be->watch, be->frontpath);
+ /* Pass in NULL node to skip exist test. */
+ frontend_changed(&be->watch, NULL);
}
-
- out:
- if (frontend)
- kfree(frontend);
- return;
-
- device_fail:
- device_unregister(&be->dev->dev);
- goto out;
}
static int blkback_probe(struct xenbus_device *dev,
const struct xenbus_device_id *id)
{
struct backend_info *be;
+ char *frontend;
int err;
be = kmalloc(sizeof(*be), GFP_KERNEL);
dev->data = be;
+ frontend = NULL;
+ err = xenbus_gather(dev->nodename,
+ "frontend-id", "%li", &be->frontend_id,
+ "frontend", NULL, &frontend,
+ NULL);
+ if (XENBUS_EXIST_ERR(err))
+ goto free_be;
+ if (frontend &&
+ (strlen(frontend) == 0 || !xenbus_exists(frontend, ""))) {
+ /* If we can't get a frontend path and a frontend-id,
+ * then our bus-id is no longer valid and we need to
+ * destroy the backend device.
+ */
+ goto free_be;
+ }
+ if (err < 0) {
+ xenbus_dev_error(dev, err,
+ "reading %s/frontend or frontend-id",
+ dev->nodename);
+ goto free_be;
+ }
+
+ be->frontpath = frontend;
+ be->watch.node = be->frontpath;
+ be->watch.callback = frontend_changed;
+ err = register_xenbus_watch(&be->watch);
+ if (err) {
+ be->watch.node = NULL;
+ xenbus_dev_error(dev, err,
+ "adding frontend watch on %s",
+ be->frontpath);
+ goto free_be;
+ }
+
backend_changed(&be->backend_watch, dev->nodename);
return err;
+
free_be:
+ if (frontend)
+ kfree(frontend);
kfree(be);
return err;
}