Commit d8bf4cb3 authored by Amir Noam's avatar Amir Noam Committed by Stephen Hemminger

[bonding 2.6] fix error handling in init code

parent 367c8f00
...@@ -3470,8 +3470,9 @@ static int bond_event(struct notifier_block *this, unsigned long event, ...@@ -3470,8 +3470,9 @@ static int bond_event(struct notifier_block *this, unsigned long event,
struct net_device *event_dev = (struct net_device *)ptr; struct net_device *event_dev = (struct net_device *)ptr;
struct net_device *master = event_dev->master; struct net_device *master = event_dev->master;
if (event == NETDEV_UNREGISTER && master != NULL) if ((event == NETDEV_UNREGISTER) && (master != NULL)) {
bond_release(master, event_dev); bond_release(master, event_dev);
}
return NOTIFY_DONE; return NOTIFY_DONE;
} }
...@@ -3480,9 +3481,34 @@ static struct notifier_block bond_netdev_notifier = { ...@@ -3480,9 +3481,34 @@ static struct notifier_block bond_netdev_notifier = {
.notifier_call = bond_event, .notifier_call = bond_event,
}; };
static void bond_deinit(struct net_device *dev)
{
struct bonding *bond = dev->priv;
list_del(&bond->bond_list);
#ifdef CONFIG_PROC_FS
remove_proc_entry("info", bond->bond_proc_dir);
remove_proc_entry(dev->name, proc_net);
#endif
}
static void bond_free_all(void)
{
struct bonding *bond, *nxt;
list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
struct net_device *dev = bond->device;
unregister_netdev(dev);
bond_deinit(dev);
kfree(dev);
}
}
static int __init bond_init(struct net_device *dev) static int __init bond_init(struct net_device *dev)
{ {
bonding_t *bond; struct bonding *bond;
int count; int count;
#ifdef BONDING_DEBUG #ifdef BONDING_DEBUG
...@@ -3613,6 +3639,7 @@ bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl) ...@@ -3613,6 +3639,7 @@ bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
return -1; return -1;
} }
static int __init bonding_init(void) static int __init bonding_init(void)
{ {
int no; int no;
...@@ -3858,49 +3885,62 @@ static int __init bonding_init(void) ...@@ -3858,49 +3885,62 @@ static int __init bonding_init(void)
primary = NULL; primary = NULL;
} }
register_netdevice_notifier(&bond_netdev_notifier); rtnl_lock();
err = 0;
for (no = 0; no < max_bonds; no++) { for (no = 0; no < max_bonds; no++) {
struct net_device *dev; struct net_device *dev;
char name[IFNAMSIZ];
snprintf(name, IFNAMSIZ, "bond%d", no); dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
if (!dev) {
err = -ENOMEM;
goto out_err;
}
dev = alloc_netdev(sizeof(struct bonding), err = dev_alloc_name(dev, "bond%d");
name, ether_setup); if (err < 0) {
if (!dev) kfree(dev);
return -ENOMEM; goto out_err;
}
/* bond_init() must be called after dev_alloc_name() (for the
* /proc files), but before register_netdevice(), because we
* need to set function pointers.
*/
err = bond_init(dev);
if (err < 0) {
kfree(dev);
goto out_err;
}
dev->init = bond_init;
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
if ( (err = register_netdev(dev)) ) { err = register_netdevice(dev);
#ifdef BONDING_DEBUG if (err < 0) {
printk(KERN_INFO "%s: register_netdev failed %d\n", bond_deinit(dev);
dev->name, err);
#endif
kfree(dev); kfree(dev);
return err; goto out_err;
} }
} }
rtnl_unlock();
register_netdevice_notifier(&bond_netdev_notifier);
return 0; return 0;
out_err:
rtnl_unlock();
/* free and unregister all bonds that were successfully added */
bond_free_all();
return err;
} }
static void __exit bonding_exit(void) static void __exit bonding_exit(void)
{ {
struct bonding *bond, *nxt;
unregister_netdevice_notifier(&bond_netdev_notifier); unregister_netdevice_notifier(&bond_netdev_notifier);
bond_free_all();
list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
struct net_device *dev = bond->device;
#ifdef CONFIG_PROC_FS
remove_proc_entry("info", bond->bond_proc_dir);
remove_proc_entry(dev->name, proc_net);
#endif
unregister_netdev(dev);
free_netdev(dev);
}
} }
module_init(bonding_init); module_init(bonding_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment