diff options
author | Joey Hess <joeyh@joeyh.name> | 2015-11-13 15:20:52 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2015-11-13 15:20:52 -0400 |
commit | 664ed6564ad4ac84b9e04c3899c167cc5fe9edcb (patch) | |
tree | 381859a92e95d69408e15f12a65b6e1e39b5a102 /Utility | |
parent | f74a674dd773be1fbcfdd5967a64df9641412a1b (diff) |
also compare lock file contents to double-check link worked
And it closes the tmp file before this. I don't know if this will help
avoid lustre's craziness, but it can't hurt..
Diffstat (limited to 'Utility')
-rw-r--r-- | Utility/LockFile/PidLock.hs | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/Utility/LockFile/PidLock.hs b/Utility/LockFile/PidLock.hs index 090250f89..d2bd31c36 100644 --- a/Utility/LockFile/PidLock.hs +++ b/Utility/LockFile/PidLock.hs @@ -99,17 +99,18 @@ tryLock lockfile = trySideLock lockfile $ \sidelock -> do (tmp, h) <- openTempFile (takeDirectory lockfile) "locktmp" setFileMode tmp (combineModes readModes) hPutStr h . show =<< mkPidLock - fd <- handleToFd h + hClose h let failedlock = do - closeFd fd nukeFile tmp + maybe noop Posix.dropLock sidelock return Nothing - let tooklock = return $ Just $ LockHandle lockfile fd sidelock - ifM (linkToLock sidelock tmp lockfile) - ( do + let tooklock fd = return $ Just $ LockHandle lockfile fd sidelock + mfd <- linkToLock sidelock tmp lockfile + case mfd of + Just fd -> do nukeFile tmp - tooklock - , do + tooklock fd + Nothing -> do v <- readPidLock lockfile hn <- getHostName case v of @@ -120,9 +121,9 @@ tryLock lockfile = trySideLock lockfile $ \sidelock -> do -- we know that the pidlock is -- stale, and can take it over. rename tmp lockfile - tooklock + fd <- openFd lockfile ReadOnly Nothing defaultFileFlags + tooklock fd _ -> failedlock - ) -- Linux's open(2) man page recommends linking a pid lock into place, -- as the most portable atomic operation that will fail if @@ -140,11 +141,22 @@ tryLock lockfile = trySideLock lockfile $ \sidelock -> do -- can't do anything about such a lying filesystem. -- At least the side lock file will prevent git-annex's running on the same -- host from running concurrently even on such a lying filesystem. -linkToLock :: SideLockHandle -> FilePath -> FilePath -> IO Bool -linkToLock Nothing _ _ = return False +linkToLock :: SideLockHandle -> FilePath -> FilePath -> IO (Maybe Fd) +linkToLock Nothing _ _ = return Nothing linkToLock (Just _) src dest = do _ <- tryIO $ createLink src dest - catchDefaultIO False checklink + ifM (catchDefaultIO False checklink) + ( catchDefaultIO Nothing $ do + srccontent <- readFile src + h <- openFile dest ReadMode + destcontent <- hGetContents h + if srccontent /= destcontent + then do + hClose h + return Nothing + else Just <$> handleToFd h + , return Nothing + ) where checklink = do x <- getSymbolicLinkStatus src |