comparison mercurial/revlogutils/nodemap.py @ 47887:52018f8ef020 stable

persistent-nodemap: introduce a test to highlight possible race Weakness in the current file caching of the changelog means that a writer can end up using an outdated docket. This might result in "committed" persistent-nodemap data from a previous writer to be overwritten by a later writer. This break the strong "append only" assumption of the persistent nodemap and can result in confused reader. The race windows are quite narrow. See the test documentation for details. The issues is fixed in the next changeset. Differential Revision: https://phab.mercurial-scm.org/D11481
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 21 Sep 2021 21:18:50 +0200
parents f70ca39d0ab8
children 897aa0c4da4a
comparison
equal deleted inserted replaced
47886:016081cca1fb 47887:52018f8ef020
22 22
23 23
24 class NodeMap(dict): 24 class NodeMap(dict):
25 def __missing__(self, x): 25 def __missing__(self, x):
26 raise error.RevlogError(b'unknown node: %s' % x) 26 raise error.RevlogError(b'unknown node: %s' % x)
27
28
29 def test_race_hook_1():
30 """hook point for test
31
32 This let tests to have things happens between the docket reading and the
33 data reading"""
34 pass
27 35
28 36
29 def persisted_data(revlog): 37 def persisted_data(revlog):
30 """read the nodemap for a revlog from disk""" 38 """read the nodemap for a revlog from disk"""
31 if revlog._nodemap_file is None: 39 if revlog._nodemap_file is None:
48 docket.data_length = data_length 56 docket.data_length = data_length
49 docket.data_unused = data_unused 57 docket.data_unused = data_unused
50 58
51 filename = _rawdata_filepath(revlog, docket) 59 filename = _rawdata_filepath(revlog, docket)
52 use_mmap = revlog.opener.options.get(b"persistent-nodemap.mmap") 60 use_mmap = revlog.opener.options.get(b"persistent-nodemap.mmap")
61
62 test_race_hook_1()
53 try: 63 try:
54 with revlog.opener(filename) as fd: 64 with revlog.opener(filename) as fd:
55 if use_mmap: 65 if use_mmap:
56 try: 66 try:
57 data = util.buffer(util.mmapread(fd, data_length)) 67 data = util.buffer(util.mmapread(fd, data_length))