Commit b8a9787e authored by Jay Vosburgh's avatar Jay Vosburgh Committed by Jeff Garzik

bonding: Allow setting max_bonds to zero

	Permit bonding to function rationally if max_bonds is set to
zero.  This will load the module, but create no master devices (which can
be created via sysfs).

	Requires some change to bond_create_sysfs; currently, the
netdev sysfs directory is determined from the first bonding device created,
but this is no longer possible.  Instead, an interface from net/core is
created to create and destroy files in net_class.

	Based on a patch submitted by Phil Oester <kernel@linuxaces.com>.
Modified by Jay Vosburgh to fix the sysfs issue mentioned above and to
update the documentation.
Signed-off-by: default avatarPhil Oester <kernel@linuxace.com>
Signed-off-by: default avatarJay Vosburgh <fubar@us.ibm.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent b59f9f74
...@@ -376,7 +376,8 @@ max_bonds ...@@ -376,7 +376,8 @@ max_bonds
Specifies the number of bonding devices to create for this Specifies the number of bonding devices to create for this
instance of the bonding driver. E.g., if max_bonds is 3, and instance of the bonding driver. E.g., if max_bonds is 3, and
the bonding driver is not already loaded, then bond0, bond1 the bonding driver is not already loaded, then bond0, bond1
and bond2 will be created. The default value is 1. and bond2 will be created. The default value is 1. Specifying
a value of 0 will load bonding, but will not create any devices.
miimon miimon
......
...@@ -4750,11 +4750,11 @@ static int bond_check_params(struct bond_params *params) ...@@ -4750,11 +4750,11 @@ static int bond_check_params(struct bond_params *params)
} }
} }
if (max_bonds < 1 || max_bonds > INT_MAX) { if (max_bonds < 0 || max_bonds > INT_MAX) {
printk(KERN_WARNING DRV_NAME printk(KERN_WARNING DRV_NAME
": Warning: max_bonds (%d) not in range %d-%d, so it " ": Warning: max_bonds (%d) not in range %d-%d, so it "
"was reset to BOND_DEFAULT_MAX_BONDS (%d)\n", "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS); max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS);
max_bonds = BOND_DEFAULT_MAX_BONDS; max_bonds = BOND_DEFAULT_MAX_BONDS;
} }
...@@ -4953,7 +4953,7 @@ static int bond_check_params(struct bond_params *params) ...@@ -4953,7 +4953,7 @@ static int bond_check_params(struct bond_params *params)
printk("\n"); printk("\n");
} else { } else if (max_bonds) {
/* miimon and arp_interval not set, we need one so things /* miimon and arp_interval not set, we need one so things
* work as expected, see bonding.txt for details * work as expected, see bonding.txt for details
*/ */
......
...@@ -53,7 +53,6 @@ extern struct bond_parm_tbl arp_validate_tbl[]; ...@@ -53,7 +53,6 @@ extern struct bond_parm_tbl arp_validate_tbl[];
extern struct bond_parm_tbl fail_over_mac_tbl[]; extern struct bond_parm_tbl fail_over_mac_tbl[];
static int expected_refcount = -1; static int expected_refcount = -1;
static struct class *netdev_class;
/*--------------------------- Data Structures -----------------------------*/ /*--------------------------- Data Structures -----------------------------*/
/* Bonding sysfs lock. Why can't we just use the subsystem lock? /* Bonding sysfs lock. Why can't we just use the subsystem lock?
...@@ -1447,19 +1446,9 @@ static struct attribute_group bonding_group = { ...@@ -1447,19 +1446,9 @@ static struct attribute_group bonding_group = {
*/ */
int bond_create_sysfs(void) int bond_create_sysfs(void)
{ {
int ret = 0; int ret;
struct bonding *firstbond;
/* get the netdev class pointer */
firstbond = container_of(bond_dev_list.next, struct bonding, bond_list);
if (!firstbond)
return -ENODEV;
netdev_class = firstbond->dev->dev.class;
if (!netdev_class)
return -ENODEV;
ret = class_create_file(netdev_class, &class_attr_bonding_masters); ret = netdev_class_create_file(&class_attr_bonding_masters);
/* /*
* Permit multiple loads of the module by ignoring failures to * Permit multiple loads of the module by ignoring failures to
* create the bonding_masters sysfs file. Bonding devices * create the bonding_masters sysfs file. Bonding devices
...@@ -1478,10 +1467,6 @@ int bond_create_sysfs(void) ...@@ -1478,10 +1467,6 @@ int bond_create_sysfs(void)
printk(KERN_ERR printk(KERN_ERR
"network device named %s already exists in sysfs", "network device named %s already exists in sysfs",
class_attr_bonding_masters.attr.name); class_attr_bonding_masters.attr.name);
else {
netdev_class = NULL;
return 0;
}
} }
return ret; return ret;
...@@ -1493,8 +1478,7 @@ int bond_create_sysfs(void) ...@@ -1493,8 +1478,7 @@ int bond_create_sysfs(void)
*/ */
void bond_destroy_sysfs(void) void bond_destroy_sysfs(void)
{ {
if (netdev_class) netdev_class_remove_file(&class_attr_bonding_masters);
class_remove_file(netdev_class, &class_attr_bonding_masters);
} }
/* /*
......
...@@ -1506,6 +1506,9 @@ extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos); ...@@ -1506,6 +1506,9 @@ extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
extern void dev_seq_stop(struct seq_file *seq, void *v); extern void dev_seq_stop(struct seq_file *seq, void *v);
#endif #endif
extern int netdev_class_create_file(struct class_attribute *class_attr);
extern void netdev_class_remove_file(struct class_attribute *class_attr);
extern void linkwatch_run_queue(void); extern void linkwatch_run_queue(void);
extern int netdev_compute_features(unsigned long all, unsigned long one); extern int netdev_compute_features(unsigned long all, unsigned long one);
......
...@@ -468,6 +468,19 @@ int netdev_register_kobject(struct net_device *net) ...@@ -468,6 +468,19 @@ int netdev_register_kobject(struct net_device *net)
return device_add(dev); return device_add(dev);
} }
int netdev_class_create_file(struct class_attribute *class_attr)
{
return class_create_file(&net_class, class_attr);
}
void netdev_class_remove_file(struct class_attribute *class_attr)
{
class_remove_file(&net_class, class_attr);
}
EXPORT_SYMBOL(netdev_class_create_file);
EXPORT_SYMBOL(netdev_class_remove_file);
void netdev_initialize_kobject(struct net_device *net) void netdev_initialize_kobject(struct net_device *net)
{ {
struct device *device = &(net->dev); struct device *device = &(net->dev);
......
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