.. of functions declared with __must_check post-2.6.18.
This implies completely suppressing frontend/backend operations if the
respective bus or device registration failed.
(Side note: When built as module, i.e. pv driver for hvm domain, failure
during module initialization appears to leave dangling pointers.)
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Index: head-2007-03-19/drivers/xen/xenbus/xenbus_probe.c
===================================================================
--- head-2007-03-19.orig/drivers/xen/xenbus/xenbus_probe.c 2007-03-21
10:18:08.000000000 +0100
+++ head-2007-03-19/drivers/xen/xenbus/xenbus_probe.c 2007-03-28
12:56:02.000000000 +0200
@@ -335,6 +335,9 @@ int xenbus_register_driver_common(struct
{
int ret;
+ if (bus->error)
+ return bus->error;
+
drv->driver.name = drv->name;
drv->driver.bus = &bus->bus;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
@@ -476,6 +479,9 @@ int xenbus_probe_node(struct xen_bus_typ
enum xenbus_state state = xenbus_read_driver_state(nodename);
+ if (bus->error)
+ return bus->error;
+
if (state != XenbusStateInitialising) {
/* Device is not new, so ignore it. This can happen if a
device is going away after switching to Closed. */
@@ -513,10 +519,18 @@ int xenbus_probe_node(struct xen_bus_typ
if (err)
goto fail;
- device_create_file(&xendev->dev, &dev_attr_nodename);
- device_create_file(&xendev->dev, &dev_attr_devtype);
+ err = device_create_file(&xendev->dev, &dev_attr_nodename);
+ if (err)
+ goto unregister;
+ err = device_create_file(&xendev->dev, &dev_attr_devtype);
+ if (err)
+ goto unregister;
return 0;
+unregister:
+ device_remove_file(&xendev->dev, &dev_attr_nodename);
+ device_remove_file(&xendev->dev, &dev_attr_devtype);
+ device_unregister(&xendev->dev);
fail:
kfree(xendev);
return err;
@@ -565,6 +579,9 @@ int xenbus_probe_devices(struct xen_bus_
char **dir;
unsigned int i, dir_n;
+ if (bus->error)
+ return bus->error;
+
dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
if (IS_ERR(dir))
return PTR_ERR(dir);
@@ -608,7 +625,7 @@ void dev_changed(const char *node, struc
char type[BUS_ID_SIZE];
const char *p, *root;
- if (char_count(node, '/') < 2)
+ if (bus->error || char_count(node, '/') < 2)
return;
exists = xenbus_exists(XBT_NIL, node, "");
@@ -742,7 +759,8 @@ void xenbus_suspend(void)
{
DPRINTK("");
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
+ if (!xenbus_frontend.error)
+ bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
xenbus_backend_suspend(suspend_dev);
xs_suspend();
}
@@ -752,7 +770,8 @@ void xenbus_resume(void)
{
xb_init_comms();
xs_resume();
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
+ if (!xenbus_frontend.error)
+ bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
xenbus_backend_resume(resume_dev);
}
EXPORT_SYMBOL_GPL(xenbus_resume);
@@ -760,7 +779,8 @@ EXPORT_SYMBOL_GPL(xenbus_resume);
void xenbus_suspend_cancel(void)
{
xs_suspend_cancel();
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_cancel_dev);
+ if (!xenbus_frontend.error)
+ bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
suspend_cancel_dev);
xenbus_backend_resume(suspend_cancel_dev);
}
EXPORT_SYMBOL_GPL(xenbus_suspend_cancel);
@@ -854,7 +874,11 @@ static int __init xenbus_probe_init(void
return -ENODEV;
/* Register ourselves with the kernel bus subsystem */
- bus_register(&xenbus_frontend.bus);
+ xenbus_frontend.error = bus_register(&xenbus_frontend.bus);
+ if (xenbus_frontend.error)
+ printk(KERN_WARNING
+ "XENBUS: Error registering frontend bus: %i\n",
+ xenbus_frontend.error);
xenbus_backend_bus_register();
/*
@@ -925,7 +949,15 @@ static int __init xenbus_probe_init(void
}
/* Register ourselves with the kernel device subsystem */
- device_register(&xenbus_frontend.dev);
+ if (!xenbus_frontend.error) {
+ xenbus_frontend.error = device_register(&xenbus_frontend.dev);
+ if (xenbus_frontend.error) {
+ bus_unregister(&xenbus_frontend.bus);
+ printk(KERN_WARNING
+ "XENBUS: Error registering frontend device:
%i\n",
+ xenbus_frontend.error);
+ }
+ }
xenbus_backend_device_register();
if (!is_initial_xendomain())
@@ -972,6 +1004,8 @@ static int is_disconnected_device(struct
static int exists_disconnected_device(struct device_driver *drv)
{
+ if (xenbus_frontend.error)
+ return xenbus_frontend.error;
return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
is_disconnected_device);
}
@@ -1036,8 +1070,10 @@ static void wait_for_devices(struct xenb
#ifndef MODULE
static int __init boot_wait_for_devices(void)
{
- ready_to_wait_for_devices = 1;
- wait_for_devices(NULL);
+ if (!xenbus_frontend.error) {
+ ready_to_wait_for_devices = 1;
+ wait_for_devices(NULL);
+ }
return 0;
}
Index: head-2007-03-19/drivers/xen/xenbus/xenbus_probe.h
===================================================================
--- head-2007-03-19.orig/drivers/xen/xenbus/xenbus_probe.h 2007-03-19
15:26:06.000000000 +0100
+++ head-2007-03-19/drivers/xen/xenbus/xenbus_probe.h 2007-03-28
12:29:34.000000000 +0200
@@ -51,6 +51,7 @@ static inline void xenbus_backend_device
struct xen_bus_type
{
char *root;
+ int error;
unsigned int levels;
int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
int (*probe)(const char *type, const char *dir);
Index: head-2007-03-19/drivers/xen/xenbus/xenbus_probe_backend.c
===================================================================
--- head-2007-03-19.orig/drivers/xen/xenbus/xenbus_probe_backend.c
2007-03-19 15:26:06.000000000 +0100
+++ head-2007-03-19/drivers/xen/xenbus/xenbus_probe_backend.c 2007-03-28
12:55:49.000000000 +0200
@@ -245,13 +245,15 @@ static struct xenbus_watch be_watch = {
void xenbus_backend_suspend(int (*fn)(struct device *, void *))
{
DPRINTK("");
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
+ if (!xenbus_backend.error)
+ bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
}
void xenbus_backend_resume(int (*fn)(struct device *, void *))
{
DPRINTK("");
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
+ if (!xenbus_backend.error)
+ bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
}
void xenbus_backend_probe_and_watch(void)
@@ -262,10 +264,23 @@ void xenbus_backend_probe_and_watch(void
void xenbus_backend_bus_register(void)
{
- bus_register(&xenbus_backend.bus);
+ xenbus_backend.error = bus_register(&xenbus_backend.bus);
+ if (xenbus_backend.error)
+ printk(KERN_WARNING
+ "XENBUS: Error registering backend bus: %i\n",
+ xenbus_backend.error);
}
void xenbus_backend_device_register(void)
{
- device_register(&xenbus_backend.dev);
+ if (xenbus_backend.error)
+ return;
+
+ xenbus_backend.error = device_register(&xenbus_backend.dev);
+ if (xenbus_backend.error) {
+ bus_unregister(&xenbus_backend.bus);
+ printk(KERN_WARNING
+ "XENBUS: Error registering backend device: %i\n",
+ xenbus_backend.error);
+ }
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|