daemon: Refactor waiting for a TunTap device to exist.

This should also fix an issue that caused excessive startup delay.
This commit is contained in:
tgoff0 2015-01-21 21:38:10 +00:00
parent d40b0dd89c
commit 6159d31f66

View file

@ -76,26 +76,47 @@ class TunTap(PyCoreNetIf):
# mutedetach(["tunctl", "-d", self.localname]) # mutedetach(["tunctl", "-d", self.localname])
self.up = False self.up = False
def waitfordevice(self): def waitfor(self, func, attempts = 10, maxretrydelay = 0.25):
'''\ '''\
Check for presence of device - tap device may not appear right Wait for func() to return zero with exponential backoff
away waits ~= stime * ( 2 ** attempts) seconds
''' '''
attempts = 9 delay = 0.01
stime = 0.01 for i in xrange(1, attempts + 1):
while attempts > 0: r = func()
try: if r == 0:
mutecheck_call([IP_BIN, "link", "show", self.localname]) return
break msg = 'attempt %s failed with nonzero exit status %s' % (i, r)
except Exception, e: if i < attempts + 1:
msg = "ip link show %s error (%d): %s" % \ msg += ', retrying...'
(self.localname, attempts, e)
if attempts > 1:
msg += ", retrying..."
self.node.info(msg) self.node.info(msg)
time.sleep(stime) time.sleep(delay)
stime *= 2 delay = delay + delay
attempts -= 1 if delay > maxretrydelay:
delay = maxretrydelay
else:
msg += ', giving up'
self.node.info(msg)
raise RuntimeError, 'command failed after %s attempts' % attempts
def waitfordevicelocal(self):
'''\
Check for presence of a local device - tap device may not
appear right away waits
'''
def localdevexists():
cmd = (IP_BIN, 'link', 'show', self.localname)
return mutecall(cmd)
self.waitfor(localdevexists)
def waitfordevicenode(self):
'''\
Check for presence of a node device - tap device may not
appear right away waits
'''
def nodedevexists():
cmd = (IP_BIN, 'link', 'show', self.name)
return self.node.cmd(cmd)
self.waitfor(nodedevexists)
def install(self): def install(self):
''' Install this TAP into its namespace. This is not done from the ''' Install this TAP into its namespace. This is not done from the
@ -103,7 +124,7 @@ class TunTap(PyCoreNetIf):
program (running on the host) has had a chance to open the socket program (running on the host) has had a chance to open the socket
end of the TAP. end of the TAP.
''' '''
self.waitfordevice() self.waitfordevicelocal()
netns = str(self.node.pid) netns = str(self.node.pid)
try: try:
check_call([IP_BIN, "link", "set", self.localname, "netns", netns]) check_call([IP_BIN, "link", "set", self.localname, "netns", netns])
@ -120,7 +141,7 @@ class TunTap(PyCoreNetIf):
def setaddrs(self): def setaddrs(self):
''' Set interface addresses based on self.addrlist. ''' Set interface addresses based on self.addrlist.
''' '''
self.waitfordevice() self.waitfordevicenode()
for addr in self.addrlist: for addr in self.addrlist:
self.node.cmd([IP_BIN, "addr", "add", str(addr), self.node.cmd([IP_BIN, "addr", "add", str(addr),
"dev", self.name]) "dev", self.name])