Patchwork D9533: persistent-nodemap: properly ignore non-existent `.nd` data file

login
register
mail settings
Submitter phabricator
Date Dec. 7, 2020, 5:53 p.m.
Message ID <differential-rev-PHID-DREV-xythpitxfrzaqyliwjql-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47818/
State Superseded
Headers show

Comments

phabricator - Dec. 7, 2020, 5:53 p.m.
SimonSapin created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This code was meant to handle the case of a nodemap docket file
  pointing to a nodemap data file that doesn’t exist (anymore),
  but most likely caused an `UnboundLocalError` exception instead
  when `data` was used on the next line without being defined.
  
  This case is theoretically possible with a race condition
  between two hg processes, but is hard to reproduce or test:
  
  - Process A reads a docket file and finds a UID in it that points to a given data file name.
  - Process B decides that this same data file needs compacting. It writes a new one with a different UID, overwrites the docket file, then removes the old data file.
  - Only then process A tries to a open a file that doesn’t exist anymore.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9533

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS




To: SimonSapin, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -58,7 +58,9 @@ 
             else:
                 data = fd.read(data_length)
     except OSError as e:
-        if e.errno != errno.ENOENT:
+        if e.errno == errno.ENOENT:
+            return None
+        else:
             raise
     if len(data) < data_length:
         return None