Fix compiler warning due to missing function prototype.
[svn.git] / tools / dev / lock-check.py
blob0aa8ce10a4f04d56fe658ba3db996e0362515ff8
1 #!/usr/bin/env python
3 ### Repository lock checker. Gets an exclusive lock on the provided
4 ### repository, then runs db_stat to see if the lock counts have been
5 ### reset to 0. If not, prints the timestamp of the run and a message
6 ### about accumulation.
8 DB_STAT = 'db_stat'
11 import sys
12 import os
13 import os.path
14 import time
15 import fcntl
16 import getopt
17 try:
18 my_getopt = getopt.gnu_getopt
19 except AttributeError:
20 my_getopt = getopt.getopt
22 def usage_and_exit(retval):
23 if retval:
24 out = sys.stderr
25 else:
26 out = sys.stdout
27 out.write("""Usage: %s [OPTIONS] REPOS-PATH
29 Options:
30 --help (-h) : Show this usage message
31 --non-blocking : Don't wait for a lock that can't be immediately obtained
33 Obtain an exclusive lock (waiting for one unless --non-blocking is
34 passed) on REPOS-PATH, then check its lock usage counts. If there is
35 any accumulation present, report that accumulation to stdout.
36 """ % (os.path.basename(sys.argv[0])))
37 sys.exit(retval)
39 def main():
40 now_time = time.asctime()
41 repos_path = None
42 nonblocking = 0
44 # Parse the options.
45 optlist, args = my_getopt(sys.argv[1:], "h", ['non-blocking', 'help'])
46 for opt, arg in optlist:
47 if opt == '--help' or opt == '-h':
48 usage_and_exit(0)
49 if opt == '--non-blocking':
50 nonblocking = 1
51 else:
52 usage_and_exit(1)
54 # We need at least a path to work with, here.
55 argc = len(args)
56 if argc < 1 or argc > 1:
57 usage_and_exit(1)
58 repos_path = args[0]
60 fd = open(os.path.join(repos_path, 'locks', 'db.lock'), 'a')
61 try:
62 # Get an exclusive lock on the repository lock file, but maybe
63 # don't wait for it.
64 try:
65 mode = fcntl.LOCK_EX
66 if nonblocking:
67 mode = mode | fcntl.LOCK_NB
68 fcntl.lockf(fd, mode)
69 except IOError:
70 sys.stderr.write("Error obtaining exclusive lock.\n")
71 sys.exit(1)
73 # Grab the db_stat results.
74 lines = os.popen('%s -ch %s' % (DB_STAT, os.path.join(repos_path, 'db')))
75 log_lines = []
76 for line in lines:
77 pieces = line.split('\t')
78 if (pieces[1].find('current lock') != -1) and (int(pieces[0]) > 0):
79 log = ''
80 if not len(log_lines):
81 log = log + "[%s] Lock accumulation for '%s'\n" \
82 % (now_time, repos_path)
83 log = log + ' ' * 27
84 log = log + "%s\t%s" % (pieces[0], pieces[1])
85 log_lines.append(log)
86 if len(log_lines):
87 sys.stdout.write(''.join(log_lines))
88 finally:
89 # Unlock the lockfile
90 fcntl.lockf(fd, fcntl.LOCK_UN)
91 fd.close()
93 if __name__ == "__main__":
94 main()