ia64/xen-unstable

view tools/python/xen/xend/XendPIF.py @ 13220:c731c158f63c

Remove a few more explicit type conversions, now that stringify is fixed.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Thu Dec 28 16:52:44 2006 +0000 (2006-12-28)
parents d759e9df902f
children b97780b7080d
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (c) 2006 Xensource Inc.
16 #============================================================================
18 import commands
19 import logging
20 import os
21 import re
24 log = logging.getLogger("xend.XendPIF")
25 log.setLevel(logging.TRACE)
28 MAC_RE = re.compile(':'.join(['[0-9a-f]{2}'] * 6))
29 IP_IFACE_RE = re.compile(r'^\d+: (\w+):.*mtu (\d+) .* link/\w+ ([0-9a-f:]+)')
31 def linux_phy_to_virt(pif_name):
32 return 'eth' + re.sub(r'^[a-z]+', '', pif_name)
34 def linux_get_phy_ifaces():
35 """Returns a list of physical interfaces.
37 Identifies PIFs as those that have a interface name starting with 'p'
38 and have the fake 'fe:ff:ff:ff:ff:ff' MAC address.
40 See /etc/xen/scripts/network-bridge for how the devices are renamed.
42 @rtype: array of 3-element tuple (name, mtu, mac)
43 """
45 ip_cmd = 'ip -o link show'
46 rc, output = commands.getstatusoutput(ip_cmd)
47 ifaces = {}
48 phy_ifaces = []
49 if rc == 0:
50 # parse all interfaces into (name, mtu, mac)
51 for line in output.split('\n'):
52 has_if = re.search(IP_IFACE_RE, line)
53 if has_if:
54 ifaces[has_if.group(1)] = has_if.groups()
56 # resolve pifs' mac addresses
57 for name, mtu, mac in ifaces.values():
58 if name[0] == 'p' and mac == 'fe:ff:ff:ff:ff:ff':
59 bridged_ifname = linux_phy_to_virt(name)
60 bridged_if = ifaces.get(bridged_ifname)
61 if bridged_if:
62 bridged_mac = bridged_if[2]
63 phy_ifaces.append((name, int(mtu), bridged_mac))
65 return phy_ifaces
67 def linux_set_mac(iface, mac):
68 if not re.search(MAC_RE, mac):
69 return False
71 ip_mac_cmd = 'ip link set %s addr %s' % \
72 (linux_phy_to_virt(iface), mac)
73 rc, output = commands.getstatusoutput(ip_mac_cmd)
74 if rc == 0:
75 return True
77 return False
79 def linux_set_mtu(iface, mtu):
80 try:
81 ip_mtu_cmd = 'ip link set %s mtu %d' % \
82 (linux_phy_to_virt(iface), int(mtu))
83 rc, output = commands.getstatusoutput(ip_mtu_cmd)
84 if rc == 0:
85 return True
86 return False
87 except ValueError:
88 return False
90 class XendPIF:
91 """Representation of a Physical Network Interface."""
93 def __init__(self, uuid, name, mtu, vlan, mac, network, host):
94 self.uuid = uuid
95 self.name = name
96 self.mac = mac
97 self.mtu = mtu
98 self.vlan = vlan
99 self.network = network
100 self.host = host
102 def set_name(self, new_name):
103 self.name = new_name
105 def set_mac(self, new_mac):
106 success = linux_set_mac(new_mac)
107 if success:
108 self.mac = new_mac
109 return success
111 def set_mtu(self, new_mtu):
112 success = linux_set_mtu(new_mtu)
113 if success:
114 self.mtu = new_mtu
115 return success
117 def get_io_read_kbs(self):
118 return 0.0
120 def get_io_write_kbs(self):
121 return 0.0
123 def get_record(self, transient = True):
124 result = {'name': self.name,
125 'MAC': self.mac,
126 'MTU': self.mtu,
127 'VLAN': self.vlan,
128 'host': self.host.uuid,
129 'network': self.network.uuid}
130 if transient:
131 result['io_read_kbs'] = self.get_io_read_kbs()
132 result['io_write_kbs'] = self.get_io_write_kbs()
133 return result
136 def refresh(self, bridges):
137 ifname = self.interface_name()
138 rc, _ = _cmd('ip link show %s', ifname)
139 if rc != 0:
140 # Interface does not exist. If it's a physical interface, then
141 # there's nothing we can do -- this should have been set up with
142 # the network script. Otherwise, we can use vconfig to derive
143 # a subinterface.
144 if not self.vlan:
145 return
147 rc, _ = _cmd('vconfig add %s %s', self.name, self.vlan)
148 if rc != 0:
149 log.error('Could not refresh %s', ifname)
150 return
151 log.info('Created network interface %s', ifname)
153 for brname, nics in bridges.items():
154 if ifname in nics:
155 log.debug('%s is already attached to %s', ifname, brname)
156 return
158 # The interface is not attached to a bridge. Create one, and attach
159 # the interface to it.
160 brname = _new_bridge_name(bridges)
161 rc, _ = _cmd('brctl addbr %s', brname)
162 if rc != 0:
163 log.error('Could not create bridge %s for interface %s', brname,
164 ifname)
165 return
166 log.info('Created network bridge %s', brname)
168 rc, _ = _cmd('brctl addif %s %s', brname, ifname)
169 if rc != 0:
170 log.error('Could not add %s to %s', ifname, brname)
171 return
172 log.info('Added network interface %s to bridge %s', ifname, brname)
175 def interface_name(self):
176 if self.vlan:
177 return '%s.%s' % (self.name, self.vlan)
178 else:
179 return self.name
182 def _cmd(cmd, *args):
183 if len(args) > 0:
184 cmd = cmd % args
185 rc, output = commands.getstatusoutput(cmd)
186 if rc != 0:
187 log.debug('%s failed with code %d' % (cmd, rc))
188 log.trace('%s: %s' % (cmd, output))
189 return rc, output
192 def _new_bridge_name(bridges):
193 n = 0
194 while True:
195 brname = 'xenbr%d' % n
196 if brname not in bridges:
197 return brname
198 n += 1