From dd8e37e0d1fe9db8b3dace3af1d0fedc60eca6b3 Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Fri, 17 Jul 2009 14:35:30 -0700 Subject: Use sysfs for bonding device control Bug 4511 Since loading bond module is broken in 2.6.29 or later kernel and the root cause is in sysfs/procfs which is a mess. Workaround the problem by loading bond module once and using sysfs. (cherry picked from commit 47f054cb196959bb79960f3b6c1524b4ff7d32a8) Conflicts: templates/interfaces/bonding/node.def --- scripts/vyatta-bonding.pl | 64 ++++++++++------------ templates/interfaces/bonding/node.def | 13 +++-- .../interfaces/bonding/node.tag/mode/node.def | 2 + 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/scripts/vyatta-bonding.pl b/scripts/vyatta-bonding.pl index f1ff3193..2f2167fa 100755 --- a/scripts/vyatta-bonding.pl +++ b/scripts/vyatta-bonding.pl @@ -29,9 +29,9 @@ # use lib "/opt/vyatta/share/perl5/"; -use Vyatta::Config; - +use Vyatta::Interface; use Getopt::Long; + use strict; use warnings; @@ -45,52 +45,46 @@ my %modes = ( "adaptive-load-balance" => 6, ); -sub create_bond { - my $bond = shift; - my $config = new Vyatta::Config; +sub set_mode { + my ($intf, $mode) = @_; + my $val = $modes{$mode}; + die "Unknown bonding mode $mode\n" unless $val; - $config->setLevel("interfaces bonding $bond"); - my $mode = $modes{ $config->returnValue("mode") }; - defined $mode or die "bonding mode not defined"; + open my $fm, '>', "/sys/class/net/$intf/bonding/mode" + or die "Error: $intf is not a bonding device:$!\n"; + print {$fm} $val, "\n"; + close $fm + or die "Error: $intf can not set mode $val:$!\n"; +} - system("sudo modprobe -o \"$bond\" bonding mode=$mode") == 0 - or die "modprobe of bonding failed: $!\n"; - system("sudo ip link set \"$bond\" up") == 0 - or die "enabling $bond failed: $!\n"; -} +sub change_mode { + my ($intf, $mode) = @_; + my $interface = new Vyatta::Interface($intf); -sub delete_bond { - my $bond = shift; - system("sudo rmmod \"$bond\"") == 0 - or die "removal of bonding module failed: $!\n"; -} + die "$intf is not a valid interface" unless $interface; + if ($interface->up()) { + system "sudo ip link set $intf down" + and die "Could not set $intf down ($!)\n"; -# See if bonding device exists and the mode has changed -sub change_bond { - my $bond = shift; - my $config = new Vyatta::Config; + set_mode($intf, $mode); - $config->setLevel("interfaces bonding"); - if ( !( $config->isAdded($bond) || $config->isDeleted($bond) ) - && $config->isChanged("$bond mode") ) - { - delete_bond($bond); - create_bond($bond); + system "sudo ip link set $intf up" + and die "Could not set $intf up ($!)\n"; + } else { + set_mode($intf, $mode); } - exit 0; } sub usage { - print "Usage: $0 --create bondX\n"; - print " --delete bondX\n"; - print " --mode-change bondX\n"; + print "Usage: $0 --set-mode=s{2}\n"; exit 1; } +my @mode_change; + GetOptions( - 'create=s' => sub { create_bond( $_[1] ); }, - 'delete=s' => sub { delete_bond( $_[1] ); }, - 'mode-change=s' => sub { change_bond( $_[1] ); }, + 'set-mode=s{2}' => \@mode_change, ) or usage(); +change_mode( @mode_change ) if @mode_change; diff --git a/templates/interfaces/bonding/node.def b/templates/interfaces/bonding/node.def index 74e9e39d..be8baaee 100644 --- a/templates/interfaces/bonding/node.def +++ b/templates/interfaces/bonding/node.def @@ -3,13 +3,18 @@ type: txt help: Set bonding interface syntax:expression: pattern $VAR(@) "^bond[0-9]+$" \ ; "bonding must be (bond0-bond99)" -create: ${vyatta_sbindir}/vyatta-bonding.pl --create $VAR(@) +begin: if [ ! -f /sys/class/net/bonding_masters ]; then + sudo modprobe bonding max_bonds=0 + fi +create: sudo sh -c "echo +$VAR(@) > /sys/class/net/bonding_masters" || exit 1 + sudo ip link set "$VAR(@)" up + /opt/vyatta/sbin/vyatta-link-detect $VAR(@) on delete: SLAVES=`cat /sys/class/net/$VAR(@)/bonding/slaves`; - if [ -z "$SLAVES" ] - then ${vyatta_sbindir}/vyatta-bonding.pl --delete $VAR(@) + if [ -z $SLAVES ] + then + sudo sh -c "echo -$VAR(@) > /sys/class/net/bonding_masters" else echo "bonded interface $VAR(@) still has slaves: $SLAVES" exit 1; fi -end: ${vyatta_sbindir}/vyatta-bonding.pl --mode-change $VAR(@) comp_help: Enter bond interface name (bond0 - bond99) diff --git a/templates/interfaces/bonding/node.tag/mode/node.def b/templates/interfaces/bonding/node.tag/mode/node.def index 4424e95c..7e322ffc 100644 --- a/templates/interfaces/bonding/node.tag/mode/node.def +++ b/templates/interfaces/bonding/node.tag/mode/node.def @@ -8,6 +8,8 @@ syntax:expression: $VAR(@) in \ "mode must be 802.3ad, active-backup, broadcast, round-robin, \ transmit-load-balance, adaptive-load-balance, or xor" help: Sets the bonding mode +update: sudo ${vyatta_sbindir}/vyatta-bonding.pl --set-mode $VAR(../@) $VAR(@) + comp_help: Possible bonding mode 802.3ad IEEE 802.3ad Dynamic link aggregation (Default) active-backup Fault tolerant: only one slave in the bond is active -- cgit v1.2.3