]> err.no Git - linux-2.6/commitdiff
bonding: Allow setting max_bonds to zero
authorJay Vosburgh <fubar@us.ibm.com>
Sat, 14 Jun 2008 01:12:04 +0000 (18:12 -0700)
committerJeff Garzik <jgarzik@redhat.com>
Wed, 18 Jun 2008 04:00:04 +0000 (00:00 -0400)
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: Phil Oester <kernel@linuxace.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Documentation/networking/bonding.txt
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
include/linux/netdevice.h
net/core/net-sysfs.c

index 370b7da73ab4e43b3a0e26e3c55bf14672b96f3c..7fa7fe71d7a8310c00c8cade78688ece2d5250c4 100644 (file)
@@ -376,7 +376,8 @@ max_bonds
        Specifies the number of bonding devices to create for this
        instance of the bonding driver.  E.g., if max_bonds is 3, and
        the bonding driver is not already loaded, then bond0, bond1
        Specifies the number of bonding devices to create for this
        instance of the bonding driver.  E.g., if max_bonds is 3, and
        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
 
index 3b6d66a8ab9840e35c8efae00c4c12b141933ccd..d57b65dc2c72d518d3dab4c6d4f1779db23c07cd 100644 (file)
@@ -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
                       ": Warning: max_bonds (%d) not in range %d-%d, so it "
                       "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
                printk(KERN_WARNING DRV_NAME
                       ": Warning: max_bonds (%d) not in range %d-%d, so it "
                       "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)
 
                printk("\n");
 
 
                printk("\n");
 
-       } else {
+       } else if (max_bonds) {
                /* miimon and arp_interval not set, we need one so things
                 * work as expected, see bonding.txt for details
                 */
                /* miimon and arp_interval not set, we need one so things
                 * work as expected, see bonding.txt for details
                 */
index dd265c69b0dffc1b85de39bb9412a75373913b2e..6caac0ffb2f2bc575397b650da276b626f51bdd2 100644 (file)
@@ -53,7 +53,6 @@ extern struct bond_parm_tbl arp_validate_tbl[];
 extern struct bond_parm_tbl fail_over_mac_tbl[];
 
 static int expected_refcount = -1;
 extern struct bond_parm_tbl fail_over_mac_tbl[];
 
 static int expected_refcount = -1;
-static struct class *netdev_class;
 /*--------------------------- Data Structures -----------------------------*/
 
 /* Bonding sysfs lock.  Why can't we just use the subsystem lock?
 /*--------------------------- Data Structures -----------------------------*/
 
 /* Bonding sysfs lock.  Why can't we just use the subsystem lock?
@@ -1447,19 +1446,9 @@ static struct attribute_group bonding_group = {
  */
 int bond_create_sysfs(void)
 {
  */
 int bond_create_sysfs(void)
 {
-       int ret = 0;
-       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;
+       int ret;
 
 
-       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
         * create the bonding_masters sysfs file.  Bonding devices
        /*
         * Permit multiple loads of the module by ignoring failures to
         * create the bonding_masters sysfs file.  Bonding devices
@@ -1478,10 +1467,6 @@ int bond_create_sysfs(void)
                        printk(KERN_ERR
                               "network device named %s already exists in sysfs",
                               class_attr_bonding_masters.attr.name);
                        printk(KERN_ERR
                               "network device named %s already exists in sysfs",
                               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)
  */
 void bond_destroy_sysfs(void)
 {
  */
 void bond_destroy_sysfs(void)
 {
-       if (netdev_class)
-               class_remove_file(netdev_class, &class_attr_bonding_masters);
+       netdev_class_remove_file(&class_attr_bonding_masters);
 }
 
 /*
 }
 
 /*
index e92fc839ab1d9874114d2781f7eab9176c9405ba..9ccbfac3fd95aacee71c79a775c5abf873e4ea3c 100644 (file)
@@ -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);
 #endif
 
 extern void dev_seq_stop(struct seq_file *seq, void *v);
 #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 int netdev_compute_features(unsigned long all, unsigned long one);
 extern void linkwatch_run_queue(void);
 
 extern int netdev_compute_features(unsigned long all, unsigned long one);
index dccd737ea2e3396aa24824660b38095e78105f4e..3f79413192171a94bb75daf0e72b60b536857d7b 100644 (file)
@@ -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)
 {
        struct device *device = &(net->dev);
 void netdev_initialize_kobject(struct net_device *net)
 {
        struct device *device = &(net->dev);