xenbus: check function return values
PATCH 1/1 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 <[email protected]>
drivers/xen/xenbus/xenbus_probe.c +46 -10
@@ -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_typenum 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_typif (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, strucchar 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(voidreturn -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(structstatic 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 ; }
drivers/xen/xenbus/xenbus_probe.h +1 -0
@@ -51,6 +51,7 @@ static inline void xenbus_backend_devicestruct 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);
drivers/xen/xenbus/xenbus_probe_backend.c +19 -4
@@ -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(voidvoid 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); + } }