# HG changeset patch # User Pulkit Goyal <7895pulkit@gmail.com> # Date 1593764159 -19800 # Node ID 3862de62d5cf0a7152d77b4de2aa0b0252a18474 # Parent b4b6ff83ed9c4b08af5fb055bbc9911266d9883a chg: suppress OSError in _restoreio() and add some logging (issue6330) According to issue6330, running chg on heavy loaded systems can lead to following error: ``` Traceback (most recent call last): File "path-to-hg/mercurial/commandserver.py", line 650, in _acceptnewconnection self._runworker(conn) File "path-to-hg/mercurial/commandserver.py", line 701, in _runworker prereposetups=[self._reposetup], File "path-to-hg/mercurial/commandserver.py", line 470, in _serverequest sv.cleanup() File "path-to-hg/mercurial/chgserver.py", line 381, in cleanup self._restoreio() File "path-to-hg/mercurial/chgserver.py", line 444, in _restoreio os.dup2(fd, fp.fileno()) OSError: [Errno 16] Device or resource busy ``` [man dup2] indicates that, on Linux, EBUSY comes from a race condition between open() and dup2(). However it's not clear why open() race occurred for newfd=stdin/out/err. We suppress the OSError in _restoreio() since the forked worker process will finish anyway and add some logging. Thanks to Mitchell Plamann for a detailed bug description and Yuya Nishihara for suggesting the fix. diff -r b4b6ff83ed9c -r 3862de62d5cf mercurial/chgserver.py --- a/mercurial/chgserver.py Thu Jul 02 19:54:44 2020 +0200 +++ b/mercurial/chgserver.py Fri Jul 03 13:45:59 2020 +0530 @@ -442,7 +442,20 @@ if newfp is not fp: newfp.close() # restore original fd: fp is open again - os.dup2(fd, fp.fileno()) + try: + os.dup2(fd, fp.fileno()) + except OSError as err: + # According to issue6330, running chg on heavy loaded systems + # can lead to EBUSY. [man dup2] indicates that, on Linux, + # EBUSY comes from a race condition between open() and dup2(). + # However it's not clear why open() race occurred for + # newfd=stdin/out/err. + self.ui.log( + b'chgserver', + b'got %s while duplicating %s\n', + stringutil.forcebytestr(err), + fn, + ) os.close(fd) setattr(self, cn, ch) setattr(ui, fn, fp)