1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
#! /usr/bin/env python
"""
Team daemon example. Implements very basic active backup functionality.
Note that this application spawns its own team device instead of connecting
to an existing one.
Copyright (C) 2011-2013 Jiri Pirko <jiri@resnulli.us>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""
__author__ = """
jiri@resnulli.us (Jiri Pirko)
"""
import sys
import getopt
import team
import signal
def usage():
"""
Print usage of this app
"""
print "Usage: team_daemon.py [OPTION...]"
print ""
print " -h, --help print this message"
print " -t, --team-name=NAME name of team device"
print " -p, --port=NETDEV port device (can be defined multiple times)"
print " -m, --mode=MODENAME name of team mode"
sys.exit()
class TeamDaemon(object):
def __init__(self):
def_team_name = "teamtest0"
self._team_name = def_team_name
def_mode_name = "roundrobin"
self._mode_name = def_mode_name
self._port_names = []
self._old_active_hwaddr = None
self._parse_cmdline()
if self._team_name == def_team_name:
print "Using default team name \"%s\"" % def_team_name
if self._mode_name == def_mode_name:
print "Using default mode \"%s\"" % def_mode_name
print "Team name is \"%s\"" % self._team_name
self._t = team.Team(self._team_name, create=True, destroy=True)
self._t.set_mode_name(self._mode_name)
for port_name in self._port_names:
self._t.port_add(port_name)
if self._mode_name == "activebackup":
self._port_change_handler_ab = team.TeamChangeHandler(
self._port_change_handler_ab_func, None,
team.TEAM_PORT_CHANGE)
self._t.change_handler_register(self._port_change_handler_ab)
self._port_change_handler = team.TeamChangeHandler(
self._port_change_handler_func, None,
team.TEAM_PORT_CHANGE)
self._t.change_handler_register(self._port_change_handler)
self._option_change_handler = team.TeamChangeHandler(
self._option_change_handler_func, None,
team.TEAM_OPTION_CHANGE)
self._t.change_handler_register(self._option_change_handler)
def _parse_cmdline(self):
try:
opts, args = getopt.getopt(
sys.argv[1:],
"ht:p:m:",
["help", "team-name=", "port=", "mode="]
)
except getopt.GetoptError, err:
print str(err)
usage()
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
elif opt in ("-t", "--team-name"):
self._team_name = arg
elif opt in ("-p", "--port"):
self._port_names.append(arg)
elif opt in ("-m", "--mode"):
self._mode_name = arg
def _port_change_handler_func(self, unused):
print "------------------\nport change\n\tport list:"
for port in self._t.port_list():
print ("\tifname %s, linkup %d, changed %d, speed %d, duplex %d, removed %d" %
(port.ifname, port.linkup, port.changed,
port.speed, port.duplex, port.removed))
return 0
def _option_change_handler_func(self, unused):
print "------------------\noption change\n\toption list:"
for option in self._t.option_list():
print ("\t%s = %s (changed %d)" % (option.name, option.value,
option.changed))
return 0
def _change_active_port(self, old_active, new_active):
if old_active:
old_active.set_hwaddr(self._old_active_hwaddr)
self._t.set_active_port(new_active)
mac = self._t.get_hwaddr()
self._old_active_hwaddr = new_active.get_hwaddr()
new_active.set_hwaddr(mac)
print "*** new active port \"%s\" selected" % new_active
def _port_change_handler_ab_func(self, unused):
try:
active = self._t.get_active_port()
if active:
print "*** current active port is \"%s\"" % active
if active.linkup:
return
elif active.changed:
print "*** active port \"%s\" lost link" % active
except KeyError:
active = None
print "*** no current active port set"
best = None
for port in self._t.port_list():
if port.linkup:
if (not best or
port.speed > best.speed or
(port.speed == best.speed and port.duplex > port.duplex)):
best = port
if best:
self._change_active_port(active, best)
def close(self):
self._t.close()
def loop_forever(self):
self._t.loop_forever()
def kill_loop(self):
self._t.kill_loop()
def main():
team_daemon = TeamDaemon()
def kill_loop(signum, frame):
team_daemon.kill_loop()
signal.signal(signal.SIGINT, kill_loop)
signal.signal(signal.SIGHUP, kill_loop)
signal.signal(signal.SIGTERM, kill_loop)
team_daemon.loop_forever()
team_daemon.close()
if __name__ == "__main__":
main()
|