commit 6282f471e432efa2aadf1046ea6e0fbaca17b434 Author: teor teor@torproject.org Date: Thu Apr 2 19:46:26 2020 +1000
TorNet: Rename pid files after tor exits
Avoids race conditions where chutney tells tor to exit twice. And where chutney tells unrelated processes to exit.
Part of 33793. --- lib/chutney/TorNet.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/lib/chutney/TorNet.py b/lib/chutney/TorNet.py index ff6acf6..b68b240 100644 --- a/lib/chutney/TorNet.py +++ b/lib/chutney/TorNet.py @@ -966,11 +966,10 @@ class LocalNodeController(NodeController): return LocalNodeController.NODE_WAIT_FOR_UNCHECKED_DIR_INFO
def getPid(self): - """Assuming that this node has its pidfile in ${dir}/pid, return - the pid of the running process, or None if there is no pid in the - file. + """Read the pidfile, and return the pid of the running process. + Returns None if there is no pid in the file. """ - pidfile = os.path.join(self._env['dir'], 'pid') + pidfile = self._env['pidfile'] if not os.path.exists(pidfile): return None
@@ -1111,6 +1110,14 @@ class LocalNodeController(NodeController): .format(self._env['nick'])) os.remove(lf)
+ def cleanup_pidfile(self): + pidfile = self._env['pidfile'] + if not self.isRunning() and os.path.exists(pidfile): + debug("Renaming stale pid file for {} ..." + .format(self._env['nick'])) + # Move the pidfile, so that we don't try to stop the process again + os.rename(pidfile, pidfile + ".old") + def waitOnLaunch(self): """Check whether we can wait() for the tor process to launch""" # TODO: is this the best place for this code? @@ -1925,6 +1932,9 @@ class TorEnviron(chutney.Templating.Environ): def _get_lockfile(self, my): return os.path.join(self['dir'], 'lock')
+ def _get_pidfile(self, my): + return os.path.join(self['dir'], 'pid') + # A hs generates its key on first run, # so check for it at the last possible moment, # but cache it in memory to avoid repeatedly reading the file @@ -2360,6 +2370,7 @@ class Network(object): - wrote_dot: end a series of logged dots with a newline - any_tor_was_running: wait for STOP_WAIT_TIME for tor to stop - cleanup_runfiles: delete old lockfiles from crashed tors + rename old pid files from stopped tors ''' # make the output clearer by adding a newline if wrote_dot: @@ -2372,10 +2383,12 @@ class Network(object): time.sleep(Network.STOP_WAIT_TIME)
# check for stale lock files when Tor crashes + # move aside old pid files after Tor stops running if cleanup_runfiles: controllers = [n.getController() for n in self._nodes] for c in controllers: c.cleanup_lockfile() + c.cleanup_pidfile()
def stop(self): any_tor_was_running = False
tor-commits@lists.torproject.org