SO_REUSEADDR does not immediately free up a port when a server is killed
with a signal (which is what we do for xend stop). Since there is no
great way (at least, that I know of) to deal with this, the following
patch implements a 30 second timeout for bind to help make it highly
unlikely that we'll get burned by this.
On a very slow system, killing xend with a signal takes less than a
second for the port to become available again so 30 seconds seems really
safe. With this patch (and the previous one), I can execute the following:
while true; do xend restart && xm list || break; done
And it runs without any trouble (I ran it for an hour before finally
giving up).
Regards,
Anthony Liguori
# HG changeset patch
# User anthony@xxxxxxxxxxxxxxxxxxxxx
# Node ID 13d6ca9c35dd02770901b9a8f9f2e53c7ed500c5
# Parent 8c866d412673e4169386ee5c96ba10f20f54bf6c
SO_REUSEADDR is not enough to ensure we don't get address in use errors when
xend dies from a signal.
We implement a 30 second time to ensure we don't fail if we don't have to.
Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>
diff -r 8c866d412673 -r 13d6ca9c35dd tools/python/xen/web/tcp.py
--- a/tools/python/xen/web/tcp.py Wed Sep 14 23:47:37 2005
+++ b/tools/python/xen/web/tcp.py Thu Sep 15 00:58:12 2005
@@ -18,6 +18,7 @@
import sys
import socket
import types
+import time
from connection import *
from protocol import *
@@ -35,8 +36,25 @@
def createSocket(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- addr = (self.interface, self.port)
- sock.bind(addr)
+
+ # SO_REUSEADDR does not always ensure that we do not get an address
+ # in use error when restarted quickly
+ # we implement a timeout to try and avoid failing unnecessarily
+
+ timeout = time.time() + 30
+ again = True
+ while again and time.time() < timeout:
+ again = False
+ try:
+ sock.bind((self.interface, self.port))
+ except socket.error, (errno, strerrno):
+ if errno == 98:
+ again = True
+ else:
+ raise socket.error(errno, strerrno)
+ if again:
+ raise socket.error(98, "address in use")
+
return sock
def acceptConnection(self, sock, protocol, addr):
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|