add stat check
I have a strace taken on a lustre filesystem on which link() returned 0, but didn't actually succeed, since the file already existed. One of the linux man pages recommended using link followed by checking like this. I was reading it yesterday, but cannot find it now.
This commit is contained in:
parent
88d94e674c
commit
c2cbe5619b
1 changed files with 28 additions and 1 deletions
|
@ -92,7 +92,7 @@ tryLock lockfile = trySideLock lockfile $ \sidelock -> do
|
||||||
nukeFile tmp
|
nukeFile tmp
|
||||||
return Nothing
|
return Nothing
|
||||||
let tooklock = return $ Just $ LockHandle lockfile fd sidelock
|
let tooklock = return $ Just $ LockHandle lockfile fd sidelock
|
||||||
ifM (isJust <$> catchMaybeIO (createLink tmp lockfile))
|
ifM (linkToLock tmp lockfile)
|
||||||
( do
|
( do
|
||||||
nukeFile tmp
|
nukeFile tmp
|
||||||
tooklock
|
tooklock
|
||||||
|
@ -111,6 +111,33 @@ tryLock lockfile = trySideLock lockfile $ \sidelock -> do
|
||||||
_ -> failedlock
|
_ -> failedlock
|
||||||
)
|
)
|
||||||
|
|
||||||
|
-- Linux man pages recommend linking a pid lock into place,
|
||||||
|
-- as the most portable atomic operation that will fail if
|
||||||
|
-- it already exists. However, on some network filesystems,
|
||||||
|
-- link will return success sometimes despite having failed,
|
||||||
|
-- so we have to stat both files to check if it actually worked.
|
||||||
|
linkToLock :: FilePath -> FilePath -> IO Bool
|
||||||
|
linkToLock src dest = ifM (isJust <$> catchMaybeIO (createLink src dest))
|
||||||
|
( catchDefaultIO False checklink
|
||||||
|
, return False
|
||||||
|
)
|
||||||
|
where
|
||||||
|
checklink = do
|
||||||
|
x <- getSymbolicLinkStatus src
|
||||||
|
y <- getSymbolicLinkStatus dest
|
||||||
|
return $ and
|
||||||
|
[ deviceID x == deviceID y
|
||||||
|
, fileID x == fileID y
|
||||||
|
, fileMode x == fileMode y
|
||||||
|
, linkCount x == linkCount y
|
||||||
|
, fileOwner x == fileOwner y
|
||||||
|
, fileGroup x == fileGroup y
|
||||||
|
, specialDeviceID x == specialDeviceID y
|
||||||
|
, fileSize x == fileSize y
|
||||||
|
, modificationTime x == modificationTime y
|
||||||
|
, isRegularFile x == isRegularFile y
|
||||||
|
]
|
||||||
|
|
||||||
-- | Waits as necessary to take a lock.
|
-- | Waits as necessary to take a lock.
|
||||||
--
|
--
|
||||||
-- Uses a 1 second wait-loop.
|
-- Uses a 1 second wait-loop.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue