Mercurial > public > mercurial-scm > hg
comparison mercurial/vfs.py @ 51649:ba205f944cb4 stable
mmap: add a `is_mmap_safe` method to vfs
This will be useful to safeguard mmap usage to void SIGBUS when repositories
lives on a NFS drive.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 03 Jul 2024 12:22:48 +0200 |
parents | b5500857e173 |
children | be6d8ea6d3d2 |
comparison
equal
deleted
inserted
replaced
51647:5b803e5c1325 | 51649:ba205f944cb4 |
---|---|
186 def lexists(self, path: Optional[bytes] = None) -> bool: | 186 def lexists(self, path: Optional[bytes] = None) -> bool: |
187 return os.path.lexists(self.join(path)) | 187 return os.path.lexists(self.join(path)) |
188 | 188 |
189 def lstat(self, path: Optional[bytes] = None): | 189 def lstat(self, path: Optional[bytes] = None): |
190 return os.lstat(self.join(path)) | 190 return os.lstat(self.join(path)) |
191 | |
192 def is_mmap_safe(self, path: Optional[bytes] = None) -> bool: | |
193 """return True if it is safe to read a file content as mmap | |
194 | |
195 This focus on the file system aspect of such safety, the application | |
196 logic around that file is not taken into account, so caller need to | |
197 make sure the file won't be truncated in a way that will create SIGBUS | |
198 on access. | |
199 | |
200 | |
201 The initial motivation for this logic is that if mmap is used on NFS | |
202 and somebody deletes the mapped file (e.g. by renaming on top of it), | |
203 then you get SIGBUS, which can be pretty disruptive: we get core dump | |
204 reports, and the process terminates without writing to the blackbox. | |
205 | |
206 Instead in this situation we prefer to read the file normally. | |
207 The risk of ESTALE in the middle of the read remains, but it's | |
208 smaller because we read sooner and the error should be reported | |
209 just as any other error. | |
210 | |
211 Note that python standard library does not offer the necessary function | |
212 to detect the file stem bits. So this detection rely on compiled bits | |
213 and is not available in pure python. | |
214 """ | |
215 # XXX Since we already assume a vfs to address a consistent file system | |
216 # in other location, we could determine the fstype once for the root | |
217 # and cache that value. | |
218 fstype = util.getfstype(self.join(path)) | |
219 return fstype is not None and fstype != b'nfs' | |
191 | 220 |
192 def listdir(self, path: Optional[bytes] = None): | 221 def listdir(self, path: Optional[bytes] = None): |
193 return os.listdir(self.join(path)) | 222 return os.listdir(self.join(path)) |
194 | 223 |
195 def makedir(self, path: Optional[bytes] = None, notindexed=True): | 224 def makedir(self, path: Optional[bytes] = None, notindexed=True): |