[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] xenbus: check function return values



.. 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.