jadmanski | 6dadd83 | 2009-02-05 23:39:27 +0000 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | |
| 3 | import common |
| 4 | import sys, os, signal, time, subprocess, fcntl |
| 5 | |
| 6 | logdir = sys.argv[1] |
| 7 | stdout_start = int(sys.argv[2]) # number of bytes we can skip on stdout |
| 8 | stderr_start = int(sys.argv[3]) # nubmer of bytes we can skip on stderr |
Simran Basi | bca10a6 | 2013-01-24 15:52:35 -0800 | [diff] [blame] | 9 | # TODO (crosbug.com/38224)- sbasi: Remove extra logging. |
| 10 | stderr = open(os.path.join(logdir, 'stderr'), 'a', 0) |
jadmanski | 6dadd83 | 2009-02-05 23:39:27 +0000 | [diff] [blame] | 11 | |
Simran Basi | bca10a6 | 2013-01-24 15:52:35 -0800 | [diff] [blame] | 12 | print >> stderr, 'Entered autotestd_monitor.' |
jadmanski | c641fd7 | 2009-04-03 21:50:11 +0000 | [diff] [blame] | 13 | # if any of our tail processes die, the monitor should die too |
| 14 | def kill_self(signum, frame): |
| 15 | os.kill(os.getpid(), signal.SIGTERM) |
| 16 | signal.signal(signal.SIGCHLD, kill_self) |
| 17 | |
jadmanski | 6dadd83 | 2009-02-05 23:39:27 +0000 | [diff] [blame] | 18 | devnull = open(os.devnull, 'w') |
| 19 | |
| 20 | # launch some tail processes to pump the std* streams |
| 21 | def launch_tail(filename, outstream, start): |
| 22 | path = os.path.join(logdir, filename) |
| 23 | argv = ['tail', '--retry', '--follow=name', '--bytes=+%d' % start, path] |
| 24 | # stdout=sys.stdout fails on pre-2.5 python (bug in subprocess module) |
| 25 | if outstream != subprocess.PIPE and outstream.fileno() == 1: |
| 26 | return subprocess.Popen(argv, stderr=devnull) |
| 27 | else: |
| 28 | return subprocess.Popen(argv, stdout=outstream, stderr=devnull) |
| 29 | stdout_pump = launch_tail('stdout', sys.stdout, stdout_start) |
| 30 | stderr_pump = launch_tail('stderr', sys.stderr, stderr_start) |
| 31 | |
Simran Basi | bca10a6 | 2013-01-24 15:52:35 -0800 | [diff] [blame] | 32 | print >> stderr, 'Finished launching tail subprocesses.' |
| 33 | |
jadmanski | f3fbce8 | 2009-02-18 18:54:33 +0000 | [diff] [blame] | 34 | # wait for logdir/started to exist to be sure autotestd is started |
| 35 | start_time = time.time() |
| 36 | started_file_path = os.path.join(logdir, 'started') |
| 37 | while not os.path.exists(started_file_path): |
| 38 | time.sleep(1) |
| 39 | if time.time() - start_time >= 30: |
| 40 | raise Exception("autotestd failed to start in %s" % logdir) |
jadmanski | f3fbce8 | 2009-02-18 18:54:33 +0000 | [diff] [blame] | 41 | |
Simran Basi | bca10a6 | 2013-01-24 15:52:35 -0800 | [diff] [blame] | 42 | print >> stderr, 'Finished waiting on autotestd to start.' |
| 43 | |
jadmanski | 6dadd83 | 2009-02-05 23:39:27 +0000 | [diff] [blame] | 44 | # watch the exit code file for an exit |
| 45 | exit_code_file = open(os.path.join(logdir, 'exit_code')) |
| 46 | fcntl.flock(exit_code_file, fcntl.LOCK_EX) |
Simran Basi | bca10a6 | 2013-01-24 15:52:35 -0800 | [diff] [blame] | 47 | print >> stderr, 'Got lock of exit_code_file.' |
jadmanski | 6dadd83 | 2009-02-05 23:39:27 +0000 | [diff] [blame] | 48 | try: |
| 49 | exit_code = exit_code_file.read() |
| 50 | if len(exit_code) != 4: |
| 51 | exit_code = -signal.SIGKILL # autotestd was nuked |
| 52 | else: |
| 53 | exit_code = int(exit_code) |
| 54 | finally: |
| 55 | fcntl.flock(exit_code_file, fcntl.LOCK_UN) |
| 56 | exit_code_file.close() |
Simran Basi | bca10a6 | 2013-01-24 15:52:35 -0800 | [diff] [blame] | 57 | print >> stderr, 'Released lock of exit_code_file and closed it.' |
jadmanski | 6dadd83 | 2009-02-05 23:39:27 +0000 | [diff] [blame] | 58 | |
jadmanski | 263313e | 2009-07-01 16:26:03 +0000 | [diff] [blame] | 59 | # tail runs in 1s polling loop, so give them a chance to finish |
| 60 | time.sleep(2) |
Simran Basi | bca10a6 | 2013-01-24 15:52:35 -0800 | [diff] [blame] | 61 | |
| 62 | print >> stderr, 'Killing child processes.' |
jadmanski | 263313e | 2009-07-01 16:26:03 +0000 | [diff] [blame] | 63 | # clear the SIGCHLD handler so that killing the tails doesn't kill us |
| 64 | signal.signal(signal.SIGCHLD, signal.SIG_DFL) |
jadmanski | 6dadd83 | 2009-02-05 23:39:27 +0000 | [diff] [blame] | 65 | os.kill(stdout_pump.pid, signal.SIGTERM) |
| 66 | os.kill(stderr_pump.pid, signal.SIGTERM) |
| 67 | |
| 68 | # exit (with the same code as autotestd) |
| 69 | sys.exit(exit_code) |