aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2005-11-09 13:36:04 -0500
committerJohn W. Linville <linville@tuxdriver.com>2005-11-13 14:48:20 -0500
commitdfe60397a62b1a5ebc7f05fd65463d3e29397677 (patch)
tree4f11c617486af7497356edfd87c276d81ed466d6 /drivers/net
parenta77b53258d76513c37e766dc0db1fc9db7c4ac1e (diff)
[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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bonding/bond_main.c113
-rw-r--r--drivers/net/bonding/bonding.h1
2 files changed, 62 insertions, 52 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index b8d617626c90..2475b76e10e4 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4898,81 +4898,90 @@ static int bond_check_params(struct bond_params *params)
4898 return 0; 4898 return 0;
4899} 4899}
4900 4900
4901/* Create a new bond based on the specified name and bonding parameters.
4902 * Caller must NOT hold rtnl_lock; we need to release it here before we
4903 * set up our sysfs entries.
4904 */
4905int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
4906{
4907 struct net_device *bond_dev;
4908 int res;
4909
4910 rtnl_lock();
4911 bond_dev = alloc_netdev(sizeof(struct bonding), name, ether_setup);
4912 if (!bond_dev) {
4913 printk(KERN_ERR DRV_NAME
4914 ": %s: eek! can't alloc netdev!\n",
4915 name);
4916 res = -ENOMEM;
4917 goto out_rtnl;
4918 }
4919
4920 /* bond_init() must be called after dev_alloc_name() (for the
4921 * /proc files), but before register_netdevice(), because we
4922 * need to set function pointers.
4923 */
4924
4925 res = bond_init(bond_dev, params);
4926 if (res < 0) {
4927 goto out_netdev;
4928 }
4929
4930 SET_MODULE_OWNER(bond_dev);
4931
4932 res = register_netdevice(bond_dev);
4933 if (res < 0) {
4934 goto out_bond;
4935 }
4936 if (newbond)
4937 *newbond = bond_dev->priv;
4938
4939 rtnl_unlock(); /* allows sysfs registration of net device */
4940 goto done;
4941out_bond:
4942 bond_deinit(bond_dev);
4943out_netdev:
4944 free_netdev(bond_dev);
4945out_rtnl:
4946 rtnl_unlock();
4947done:
4948 return res;
4949}
4950
4901static int __init bonding_init(void) 4951static int __init bonding_init(void)
4902{ 4952{
4903 struct bond_params params;
4904 int i; 4953 int i;
4905 int res; 4954 int res;
4955 char new_bond_name[8]; /* Enough room for 999 bonds at init. */
4906 4956
4907 printk(KERN_INFO "%s", version); 4957 printk(KERN_INFO "%s", version);
4908 4958
4909 res = bond_check_params(&params); 4959 res = bond_check_params(&bonding_defaults);
4910 if (res) { 4960 if (res) {
4911 return res; 4961 goto out;
4912 } 4962 }
4913 4963
4914 rtnl_lock();
4915
4916#ifdef CONFIG_PROC_FS 4964#ifdef CONFIG_PROC_FS
4917 bond_create_proc_dir(); 4965 bond_create_proc_dir();
4918#endif 4966#endif
4919
4920 for (i = 0; i < max_bonds; i++) { 4967 for (i = 0; i < max_bonds; i++) {
4921 struct net_device *bond_dev; 4968 sprintf(new_bond_name, "bond%d",i);
4922 4969 res = bond_create(new_bond_name,&bonding_defaults, NULL);
4923 bond_dev = alloc_netdev(sizeof(struct bonding), "", ether_setup); 4970 if (res)
4924 if (!bond_dev) { 4971 goto err;
4925 res = -ENOMEM;
4926 goto out_err;
4927 }
4928
4929 res = dev_alloc_name(bond_dev, "bond%d");
4930 if (res < 0) {
4931 free_netdev(bond_dev);
4932 goto out_err;
4933 }
4934
4935 /* bond_init() must be called after dev_alloc_name() (for the
4936 * /proc files), but before register_netdevice(), because we
4937 * need to set function pointers.
4938 */
4939 res = bond_init(bond_dev, &params);
4940 if (res < 0) {
4941 free_netdev(bond_dev);
4942 goto out_err;
4943 }
4944
4945 SET_MODULE_OWNER(bond_dev);
4946
4947 res = register_netdevice(bond_dev);
4948 if (res < 0) {
4949 bond_deinit(bond_dev);
4950 free_netdev(bond_dev);
4951 goto out_err;
4952 }
4953 } 4972 }
4954 4973
4955 rtnl_unlock();
4956 register_netdevice_notifier(&bond_netdev_notifier); 4974 register_netdevice_notifier(&bond_netdev_notifier);
4957 register_inetaddr_notifier(&bond_inetaddr_notifier); 4975 register_inetaddr_notifier(&bond_inetaddr_notifier);
4958 4976
4959 return 0; 4977 goto out;
4960 4978err:
4961out_err:
4962 /*
4963 * rtnl_unlock() will run netdev_run_todo(), putting the
4964 * thus-far-registered bonding devices into a state which
4965 * unregigister_netdevice() will accept
4966 */
4967 rtnl_unlock();
4968 rtnl_lock(); 4979 rtnl_lock();
4969
4970 /* free and unregister all bonds that were successfully added */
4971 bond_free_all(); 4980 bond_free_all();
4972
4973 rtnl_unlock(); 4981 rtnl_unlock();
4974 4982out:
4975 return res; 4983 return res;
4984
4976} 4985}
4977 4986
4978static void __exit bonding_exit(void) 4987static void __exit bonding_exit(void)
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 96a733f2337a..863605aab204 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -260,6 +260,7 @@ extern inline void bond_set_slave_active_flags(struct slave *slave)
260 260
261struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); 261struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
262int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); 262int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
263int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
263void bond_deinit(struct net_device *bond_dev); 264void bond_deinit(struct net_device *bond_dev);
264int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); 265int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
265int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); 266int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);