##// END OF EJS Templates
inotify: deactivate inotify status on failure...
Benoit Boissinot -
r6996:fecf060f default
parent child Browse files
Show More
@@ -0,0 +1,15 b''
1 #!/bin/sh
2
3 "$TESTDIR/hghave" inotify || exit 80
4
5 echo "[extensions]" >> $HGRCPATH
6 echo "inotify=" >> $HGRCPATH
7
8 p="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
9 hg init $p
10 cd $p
11
12 echo % inserve
13 hg inserve
14 echo % status
15 hg status
@@ -0,0 +1,5 b''
1 % inserve
2 abort: AF_UNIX path too long
3 % status
4 failed to contact inotify server: AF_UNIX path too long
5 deactivating inotify
@@ -1,107 +1,110 b''
1 1 # __init__.py - inotify-based status acceleration for Linux
2 2 #
3 3 # Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
4 4 # Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
5 5 #
6 6 # This software may be used and distributed according to the terms
7 7 # of the GNU General Public License, incorporated herein by reference.
8 8
9 9 '''inotify-based status acceleration for Linux systems
10 10 '''
11 11
12 12 # todo: socket permissions
13 13
14 14 from mercurial.i18n import gettext as _
15 15 from mercurial import cmdutil, util
16 16 import client, errno, os, server, socket
17 17 from weakref import proxy
18 18
19 19 def serve(ui, repo, **opts):
20 20 '''start an inotify server for this repository'''
21 21 timeout = opts.get('timeout')
22 22 if timeout:
23 23 timeout = float(timeout) * 1e3
24 24
25 25 class service:
26 26 def init(self):
27 27 try:
28 28 self.master = server.Master(ui, repo, timeout)
29 29 except server.AlreadyStartedException, inst:
30 30 raise util.Abort(str(inst))
31 31
32 32 def run(self):
33 33 try:
34 34 self.master.run()
35 35 finally:
36 36 self.master.shutdown()
37 37
38 38 service = service()
39 39 cmdutil.service(opts, initfn=service.init, runfn=service.run)
40 40
41 41 def reposetup(ui, repo):
42 42 if not repo.local():
43 43 return
44 44
45 45 # XXX: weakref until hg stops relying on __del__
46 46 repo = proxy(repo)
47 47
48 48 class inotifydirstate(repo.dirstate.__class__):
49 49 # Set to True if we're the inotify server, so we don't attempt
50 50 # to recurse.
51 51 inotifyserver = False
52 52
53 53 def status(self, files, match, list_ignored, list_clean,
54 54 list_unknown=True):
55 55 try:
56 56 if not list_ignored and not self.inotifyserver:
57 57 result = client.query(ui, repo, files, match, False,
58 58 list_clean, list_unknown)
59 59 if result is not None:
60 60 return result
61 61 except socket.error, err:
62 62 if err[0] == errno.ECONNREFUSED:
63 63 ui.warn(_('(found dead inotify server socket; '
64 64 'removing it)\n'))
65 65 os.unlink(repo.join('inotify.sock'))
66 elif err[0] != errno.ENOENT:
67 raise
68 if ui.configbool('inotify', 'autostart'):
66 if err[0] in (errno.ECONNREFUSED, errno.ENOENT) and \
67 ui.configbool('inotify', 'autostart'):
69 68 query = None
70 69 ui.debug(_('(starting inotify server)\n'))
71 70 try:
72 71 server.start(ui, repo)
73 72 query = client.query
74 73 except server.AlreadyStartedException, inst:
75 74 # another process may have started its own
76 75 # inotify server while this one was starting.
77 76 ui.debug(str(inst))
78 77 query = client.query
79 78 except Exception, inst:
80 79 ui.warn(_('could not start inotify server: '
81 80 '%s\n') % inst)
82 ui.print_exc()
83
84 81 if query:
85 82 try:
86 83 return query(ui, repo, files or [], match,
87 84 list_ignored, list_clean, list_unknown)
88 85 except socket.error, err:
89 86 ui.warn(_('could not talk to new inotify '
90 'server: %s\n') % err[1])
91 ui.print_exc()
87 'server: %s\n') % err[-1])
88 else:
89 ui.warn(_('failed to contact inotify server: %s\n')
90 % err[-1])
91 ui.print_exc()
92 # replace by old status function
93 ui.warn(_('deactivating inotify\n'))
94 self.status = super(inotifydirstate, self).status
92 95
93 96 return super(inotifydirstate, self).status(
94 97 files, match or util.always, list_ignored, list_clean,
95 98 list_unknown)
96 99
97 100 repo.dirstate.__class__ = inotifydirstate
98 101
99 102 cmdtable = {
100 103 '^inserve':
101 104 (serve,
102 105 [('d', 'daemon', None, _('run server in background')),
103 106 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
104 107 ('t', 'idle-timeout', '', _('minutes to sit idle before exiting')),
105 108 ('', 'pid-file', '', _('name of file to write process ID to'))],
106 109 _('hg inserve [OPT]...')),
107 110 }
@@ -1,187 +1,195 b''
1 1 #!/usr/bin/env python
2 2 """Test the running system for features availability. Exit with zero
3 3 if all features are there, non-zero otherwise. If a feature name is
4 4 prefixed with "no-", the absence of feature is tested.
5 5 """
6 6 import optparse
7 7 import os
8 8 import re
9 9 import sys
10 10 import tempfile
11 11
12 12 tempprefix = 'hg-hghave-'
13 13
14 14 def matchoutput(cmd, regexp, ignorestatus=False):
15 15 """Return True if cmd executes successfully and its output
16 16 is matched by the supplied regular expression.
17 17 """
18 18 r = re.compile(regexp)
19 19 fh = os.popen(cmd)
20 20 s = fh.read()
21 21 ret = fh.close()
22 22 return (ignorestatus or ret is None) and r.search(s)
23 23
24 24 def has_baz():
25 25 return matchoutput('baz --version 2>&1', r'baz Bazaar version')
26 26
27 27 def has_cvs():
28 28 re = r'Concurrent Versions System.*?server'
29 29 return matchoutput('cvs --version 2>&1', re)
30 30
31 31 def has_cvsps():
32 32 return matchoutput('cvsps -h -q 2>&1', r'cvsps version', True)
33 33
34 34 def has_darcs():
35 35 return matchoutput('darcs', r'darcs version', True)
36 36
37 37 def has_mtn():
38 38 return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
39 39 'mtn --version', r'monotone 0\.(\d|[12]\d|3[01])[^\d]', True)
40 40
41 41 def has_eol_in_paths():
42 42 try:
43 43 fd, path = tempfile.mkstemp(prefix=tempprefix, suffix='\n\r')
44 44 os.close(fd)
45 45 os.remove(path)
46 46 return True
47 47 except:
48 48 return False
49 49
50 50 def has_executablebit():
51 51 fd, path = tempfile.mkstemp(prefix=tempprefix)
52 52 os.close(fd)
53 53 try:
54 54 s = os.lstat(path).st_mode
55 55 os.chmod(path, s | 0100)
56 56 return (os.lstat(path).st_mode & 0100 != 0)
57 57 finally:
58 58 os.remove(path)
59 59
60 def has_inotify():
61 try:
62 import hgext.inotify.linux.watcher
63 return True
64 except ImportError:
65 return False
66
60 67 def has_fifo():
61 68 return hasattr(os, "mkfifo")
62 69
63 70 def has_hotshot():
64 71 try:
65 72 # hotshot.stats tests hotshot and many problematic dependencies
66 73 # like profile.
67 74 import hotshot.stats
68 75 return True
69 76 except ImportError:
70 77 return False
71 78
72 79 def has_lsprof():
73 80 try:
74 81 import _lsprof
75 82 return True
76 83 except ImportError:
77 84 return False
78 85
79 86 def has_git():
80 87 return matchoutput('git --version 2>&1', r'^git version')
81 88
82 89 def has_svn():
83 90 return matchoutput('svn --version 2>&1', r'^svn, version') and \
84 91 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
85 92
86 93 def has_svn_bindings():
87 94 try:
88 95 import svn.core
89 96 return True
90 97 except ImportError:
91 98 return False
92 99
93 100 def has_symlink():
94 101 return hasattr(os, "symlink")
95 102
96 103 def has_tla():
97 104 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
98 105
99 106 def has_unix_permissions():
100 107 d = tempfile.mkdtemp(prefix=tempprefix, dir=".")
101 108 try:
102 109 fname = os.path.join(d, 'foo')
103 110 for umask in (077, 007, 022):
104 111 os.umask(umask)
105 112 f = open(fname, 'w')
106 113 f.close()
107 114 mode = os.stat(fname).st_mode
108 115 os.unlink(fname)
109 116 if mode & 0777 != ~umask & 0666:
110 117 return False
111 118 return True
112 119 finally:
113 120 os.rmdir(d)
114 121
115 122 def has_pygments():
116 123 try:
117 124 import pygments
118 125 return True
119 126 except ImportError:
120 127 return False
121 128
122 129 checks = {
123 130 "baz": (has_baz, "GNU Arch baz client"),
124 131 "cvs": (has_cvs, "cvs client/server"),
125 132 "cvsps": (has_cvsps, "cvsps utility"),
126 133 "darcs": (has_darcs, "darcs client"),
127 134 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
128 135 "execbit": (has_executablebit, "executable bit"),
129 136 "fifo": (has_fifo, "named pipes"),
130 137 "git": (has_git, "git command line client"),
131 138 "hotshot": (has_hotshot, "python hotshot module"),
139 "inotify": (has_inotify, "inotify extension support"),
132 140 "lsprof": (has_lsprof, "python lsprof module"),
133 141 "mtn": (has_mtn, "monotone client (> 0.31)"),
142 "pygments": (has_pygments, "Pygments source highlighting library"),
134 143 "svn": (has_svn, "subversion client and admin tools"),
135 144 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
136 145 "symlink": (has_symlink, "symbolic links"),
137 146 "tla": (has_tla, "GNU Arch tla client"),
138 147 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
139 "pygments": (has_pygments, "Pygments source highlighting library"),
140 148 }
141 149
142 150 def list_features():
143 151 for name, feature in checks.iteritems():
144 152 desc = feature[1]
145 153 print name + ':', desc
146 154
147 155 parser = optparse.OptionParser("%prog [options] [features]")
148 156 parser.add_option("--list-features", action="store_true",
149 157 help="list available features")
150 158 parser.add_option("-q", "--quiet", action="store_true",
151 159 help="check features silently")
152 160
153 161 if __name__ == '__main__':
154 162 options, args = parser.parse_args()
155 163 if options.list_features:
156 164 list_features()
157 165 sys.exit(0)
158 166
159 167 quiet = options.quiet
160 168
161 169 failures = 0
162 170
163 171 def error(msg):
164 172 global failures
165 173 if not quiet:
166 174 sys.stderr.write(msg + '\n')
167 175 failures += 1
168 176
169 177 for feature in args:
170 178 negate = feature.startswith('no-')
171 179 if negate:
172 180 feature = feature[3:]
173 181
174 182 if feature not in checks:
175 183 error('skipped: unknown feature: ' + feature)
176 184 continue
177 185
178 186 check, desc = checks[feature]
179 187 if not negate and not check():
180 188 error('skipped: missing feature: ' + desc)
181 189 elif negate and check():
182 190 error('skipped: system supports %s' % desc)
183 191
184 192 if failures != 0:
185 193 sys.exit(1)
186 194
187 195
General Comments 0
You need to be logged in to leave comments. Login now