diff options
author | Ben Gamari <bgamari.foss@gmail.com> | 2017-08-29 14:26:55 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-08-29 19:08:07 -0400 |
commit | f86de44dac0a6ca40c5fcd65f3a1944c45fa6011 (patch) | |
tree | 94016ec9e646d1c94aa3875ea1900eaa840ed81e /libraries/ghc-boot | |
parent | 5f6a82040694f7c8c2b394c1b418c0167b963e0b (diff) | |
download | haskell-f86de44dac0a6ca40c5fcd65f3a1944c45fa6011.tar.gz |
ghc-pkg: Try opening lockfiles in read-write mode first
As pointed out in #13945, some filesystems only allow allow exclusive
locks if the fd being locked was opened for write access. This causes
ghc-pkg to fail as it first attempts to open and exclusively lock its
lockfile in read-only mode to accomodate package databases for which we
lack write permissions (e.g. global package databases).
Instead, we now try read-write mode first, falling back to read-only
mode if this fails.
Reviewers: austin
Subscribers: rwbarton, thomie
GHC Trac Issues: #13945
Differential Revision: https://phabricator.haskell.org/D3897
Diffstat (limited to 'libraries/ghc-boot')
-rw-r--r-- | libraries/ghc-boot/GHC/PackageDb.hs | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/libraries/ghc-boot/GHC/PackageDb.hs b/libraries/ghc-boot/GHC/PackageDb.hs index bf83d25baa..9ce07e7484 100644 --- a/libraries/ghc-boot/GHC/PackageDb.hs +++ b/libraries/ghc-boot/GHC/PackageDb.hs @@ -239,15 +239,21 @@ lockPackageDbWith mode file = do -- DB for reading then we will require that the installer/packaging has -- included the lock file. -- - -- Thus the logic here is to first try opening in read-only mode (to handle - -- global read-only DBs) and if the file does not exist then try opening in - -- read/write mode to create the lock file. If either succeed then lock the - -- file. IO exceptions (other than the first open attempt failing due to the - -- file not existing) simply propagate. + -- Thus the logic here is to first try opening in read-write mode + -- and if that fails we try read-only (to handle global read-only DBs). + -- If either succeed then lock the file. IO exceptions (other than the first + -- open attempt failing due to the file not existing) simply propagate. + -- + -- Note that there is a complexity here which was discovered in #13945: some + -- filesystems (e.g. NFS) will only allow exclusive locking if the fd was + -- opened for write access. We would previously try opening the lockfile for + -- read-only access first, however this failed when run on such filesystems. + -- Consequently, we now try read-write access first, falling back to read-only + -- if are denied permission (e.g. in the case of a global database). catchJust - (\e -> if isDoesNotExistError e then Just () else Nothing) - (lockFileOpenIn ReadMode) - (const $ lockFileOpenIn ReadWriteMode) + (\e -> if isPermissionError e then Just () else Nothing) + (lockFileOpenIn ReadWriteMode) + (const $ lockFileOpenIn ReadMode) where lock = file <.> "lock" |