@@ -16,6 +16,7 @@ import atexit
import os
import signal
import sys
+import threading
import ovs.vlog
@@ -112,29 +113,29 @@ def _unlink(file_):
def _signal_handler(signr, _):
_call_hooks(signr)
- # Re-raise the signal with the default handling so that the program
- # termination status reflects that we were killed by this signal.
- signal.signal(signr, signal.SIG_DFL)
- os.kill(os.getpid(), signr)
-
def _atexit_handler():
_call_hooks(0)
-recurse = False
+mutex = threading.Lock()
def _call_hooks(signr):
- global recurse
- if recurse:
+ global mutex
+ if not mutex.acquire(blocking=False):
return
- recurse = True
for hook, cancel, run_at_exit in _hooks:
if signr != 0 or run_at_exit:
hook()
+ if signr != 0:
+ # Re-raise the signal with the default handling so that the program
+ # termination status reflects that we were killed by this signal.
+ signal.signal(signr, signal.SIG_DFL)
+ os.kill(os.getpid(), signr)
+
_inited = False
@@ -150,7 +151,9 @@ def _init():
signal.SIGALRM]
for signr in signals:
- if signal.getsignal(signr) == signal.SIG_DFL:
+ handler = signal.getsignal(signr)
+ if (handler == signal.SIG_DFL or
+ handler == signal.default_int_handler):
signal.signal(signr, _signal_handler)
atexit.register(_atexit_handler)
@@ -165,7 +168,6 @@ def signal_alarm(timeout):
if sys.platform == "win32":
import time
- import threading
class Alarm (threading.Thread):
def __init__(self, timeout):
@@ -534,29 +534,19 @@ def main():
ovsdb.close_idl()
pipes = _doexec(*([dump_cmd, '-i', mirror_interface] + tcpdargs))
- try:
- while pipes.poll() is None:
- data = pipes.stdout.readline().strip(b'\n')
- if len(data) == 0:
- raise KeyboardInterrupt
- print(data.decode('utf-8'))
- raise KeyboardInterrupt
- except KeyboardInterrupt:
- # If there is a pipe behind ovs-tcpdump (such as ovs-tcpdump
- # -i eth0 | grep "192.168.1.1"), the pipe is no longer available
- # after received Ctrl+C.
- # If we write data to an unavailable pipe, a pipe error will be
- # reported, so we turn off stdout to avoid subsequent flushing
- # of data into the pipe.
- try:
- sys.stdout.close()
- except IOError:
- pass
+ while pipes.poll() is None:
+ data = pipes.stdout.readline().strip(b'\n')
+ if len(data) == 0:
+ break
+ print(data.decode('utf-8'))
- if pipes.poll() is None:
- pipes.terminate()
+ try:
+ sys.stdout.close()
+ except IOError:
+ pass
- sys.exit(0)
+ if pipes.poll() is None:
+ pipes.terminate()
if __name__ == '__main__':
After running ovs-tcpdump and inputs multiple CTRL+C, the program will raise the following exception. Error in atexit._run_exitfuncs: Traceback (most recent call last): File "/usr/bin/ovs-tcpdump", line 421, in cleanup_mirror ovsdb = OVSDB(db_sock) File "/usr/bin/ovs-tcpdump", line 168, in __init__ OVSDB.wait_for_db_change(self._idl_conn) # Initial Sync with DB File "/usr/bin/ovs-tcpdump", line 155, in wait_for_db_change while idl.change_seqno == seq and not idl.run(): The default handler of SIGINT is default_int_handler, so it was not registered to the signal handler. When received CTRL+C again, the program was broken, and calling hook could not be executed completely. Signed-off-by: Daniel Ding <danieldin186@gmail.com> --- python/ovs/fatal_signal.py | 24 +++++++++++++----------- utilities/ovs-tcpdump.in | 32 +++++++++++--------------------- 2 files changed, 24 insertions(+), 32 deletions(-)