Skip to content

Commit

Permalink
[PATCH] bonding: move bond creation into separate function
Browse files Browse the repository at this point in the history
The sysfs interface can create bonds at runtime, so we need a separate
function to do this, instead of just doing it in the module init code.

Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Acked-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Mitch Williams authored and John W. Linville committed Nov 13, 2005
1 parent a77b532 commit dfe6039
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 52 deletions.
113 changes: 61 additions & 52 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4898,81 +4898,90 @@ static int bond_check_params(struct bond_params *params)
return 0;
}

/* Create a new bond based on the specified name and bonding parameters.
* Caller must NOT hold rtnl_lock; we need to release it here before we
* set up our sysfs entries.
*/
int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
{
struct net_device *bond_dev;
int res;

rtnl_lock();
bond_dev = alloc_netdev(sizeof(struct bonding), name, ether_setup);
if (!bond_dev) {
printk(KERN_ERR DRV_NAME
": %s: eek! can't alloc netdev!\n",
name);
res = -ENOMEM;
goto out_rtnl;
}

/* bond_init() must be called after dev_alloc_name() (for the
* /proc files), but before register_netdevice(), because we
* need to set function pointers.
*/

res = bond_init(bond_dev, params);
if (res < 0) {
goto out_netdev;
}

SET_MODULE_OWNER(bond_dev);

res = register_netdevice(bond_dev);
if (res < 0) {
goto out_bond;
}
if (newbond)
*newbond = bond_dev->priv;

rtnl_unlock(); /* allows sysfs registration of net device */
goto done;
out_bond:
bond_deinit(bond_dev);
out_netdev:
free_netdev(bond_dev);
out_rtnl:
rtnl_unlock();
done:
return res;
}

static int __init bonding_init(void)
{
struct bond_params params;
int i;
int res;
char new_bond_name[8]; /* Enough room for 999 bonds at init. */

printk(KERN_INFO "%s", version);

res = bond_check_params(&params);
res = bond_check_params(&bonding_defaults);
if (res) {
return res;
goto out;
}

rtnl_lock();

#ifdef CONFIG_PROC_FS
bond_create_proc_dir();
#endif

for (i = 0; i < max_bonds; i++) {
struct net_device *bond_dev;

bond_dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
if (!bond_dev) {
res = -ENOMEM;
goto out_err;
}

res = dev_alloc_name(bond_dev, "bond%d");
if (res < 0) {
free_netdev(bond_dev);
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.
*/
res = bond_init(bond_dev, &params);
if (res < 0) {
free_netdev(bond_dev);
goto out_err;
}

SET_MODULE_OWNER(bond_dev);

res = register_netdevice(bond_dev);
if (res < 0) {
bond_deinit(bond_dev);
free_netdev(bond_dev);
goto out_err;
}
sprintf(new_bond_name, "bond%d",i);
res = bond_create(new_bond_name,&bonding_defaults, NULL);
if (res)
goto err;
}

rtnl_unlock();
register_netdevice_notifier(&bond_netdev_notifier);
register_inetaddr_notifier(&bond_inetaddr_notifier);

return 0;

out_err:
/*
* rtnl_unlock() will run netdev_run_todo(), putting the
* thus-far-registered bonding devices into a state which
* unregigister_netdevice() will accept
*/
rtnl_unlock();
goto out;
err:
rtnl_lock();

/* free and unregister all bonds that were successfully added */
bond_free_all();

rtnl_unlock();

out:
return res;

}

static void __exit bonding_exit(void)
Expand Down
1 change: 1 addition & 0 deletions drivers/net/bonding/bonding.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ extern inline void bond_set_slave_active_flags(struct slave *slave)

struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
void bond_deinit(struct net_device *bond_dev);
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
Expand Down

0 comments on commit dfe6039

Please sign in to comment.