[PATCH] bonding: move bond creation into separate function

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>
This commit is contained in:
Mitch Williams 2005-11-09 10:36:04 -08:00 коммит произвёл John W. Linville
Родитель a77b53258d
Коммит dfe60397a6
2 изменённых файлов: 62 добавлений и 52 удалений

Просмотреть файл

@ -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)

Просмотреть файл

@ -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);