1 """ Parallel execution management """
3 __author__
= """Copyright Andy Whitcroft 2006"""
5 import sys
, logging
, os
, pickle
, traceback
, gc
, time
6 from autotest_lib
.client
.common_lib
import error
, utils
8 def fork_start(tmp
, l
):
19 except error
.AutotestError
:
22 raise error
.UnhandledTestError(e
)
23 except Exception, detail
:
26 logging
.error('child process failed')
27 # logging.exception() uses ERROR level, but we want DEBUG for
29 logging
.debug(traceback
.format_exc())
31 # note that exceptions originating in this block won't make it
33 output_dir
= os
.path
.join(tmp
, 'debug')
34 if not os
.path
.exists(output_dir
):
35 os
.makedirs(output_dir
)
36 ename
= os
.path
.join(output_dir
, "error-%d" % os
.getpid())
37 pickle
.dump(detail
, open(ename
, "w"))
42 # clear exception information to allow garbage collection of
43 # objects referenced by the exception's traceback
55 def _check_for_subprocess_exception(temp_dir
, pid
):
56 ename
= temp_dir
+ "/debug/error-%d" % pid
57 if os
.path
.exists(ename
):
58 e
= pickle
.load(file(ename
, 'r'))
59 # rename the error-pid file so that they do not affect later child
60 # processes that use recycled pids.
63 pename
= ename
+ ('-%d' % i
)
65 if not os
.path
.exists(pename
):
67 os
.rename(ename
, pename
)
71 def fork_waitfor(tmp
, pid
):
72 (pid
, status
) = os
.waitpid(pid
, 0)
74 _check_for_subprocess_exception(tmp
, pid
)
77 raise error
.TestError("Test subprocess failed rc=%d" % (status
))
79 def fork_waitfor_timed(tmp
, pid
, timeout
):
81 Waits for pid until it terminates or timeout expires.
82 If timeout expires, test subprocess is killed.
87 while time_passed
< timeout
:
89 (child_pid
, status
) = os
.waitpid(pid
, os
.WNOHANG
)
90 if (child_pid
, status
) == (0, 0):
91 time_passed
= time_passed
+ poll_time
97 logging
.info('Timer expired (%d sec.), nuking pid %d', timeout
, pid
)
99 (child_pid
, status
) = os
.waitpid(pid
, 0)
100 raise error
.TestError("Test timeout expired, rc=%d" % (status
))
102 _check_for_subprocess_exception(tmp
, pid
)
105 raise error
.TestError("Test subprocess failed rc=%d" % (status
))
107 def fork_nuke_subprocess(tmp
, pid
):
109 _check_for_subprocess_exception(tmp
, pid
)