From 5e6ced7d0f364cdcc99bde821f84361f51aa4ed5 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 10 Feb 2017 15:21:58 -0400 Subject: [PATCH] Improve pid locking code to work on filesystems that don't support hard links. Probing for hard link support in the pid locking code is redundant since git-annex init already probes that. But, it didn't seem worth threading that data through; the pid locking code runs at most once per git-annex process, and only on unusual filesystems. Optimising a single hard link and unlink isn't worth it. This commit was sponsored by Francois Marier on Patreon. --- CHANGELOG | 2 ++ Utility/LockFile/PidLock.hs | 26 +++++++++++++++---- ..._bf15b686b07c5e6e95796affa497a541._comment | 13 ++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 doc/forum/git_annex_init_timeout/comment_2_bf15b686b07c5e6e95796affa497a541._comment diff --git a/CHANGELOG b/CHANGELOG index 9e2791286b..9a5d181d6c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -49,6 +49,8 @@ git-annex (6.20170102) UNRELEASED; urgency=medium * import: Added --reinject-duplicates. * Added git template directory to Linux standalone tarball and OSX app bundle. + * Improve pid locking code to work on filesystems that don't support hard + links. -- Joey Hess Fri, 06 Jan 2017 15:22:06 -0400 diff --git a/Utility/LockFile/PidLock.hs b/Utility/LockFile/PidLock.hs index bc8ddfe6bb..87c11c01cb 100644 --- a/Utility/LockFile/PidLock.hs +++ b/Utility/LockFile/PidLock.hs @@ -150,14 +150,30 @@ tryLock lockfile = trySideLock lockfile $ \sidelock -> do -- open(2) suggests that link can sometimes appear to fail -- on NFS but have actually succeeded, and the way to find out is to stat -- the file and check its link count etc. +-- +-- However, not all filesystems support hard links. So, first probe +-- to see if they are supported. If not, use open with O_EXCL. linkToLock :: SideLockHandle -> FilePath -> FilePath -> IO Bool linkToLock Nothing _ _ = return False linkToLock (Just _) src dest = do - _ <- tryIO $ createLink src dest - ifM (catchBoolIO checklinked) - ( catchBoolIO $ not <$> checkInsaneLustre dest - , return False - ) + let probe = src ++ ".lnk" + v <- tryIO $ createLink src probe + nukeFile probe + case v of + Right _ -> do + _ <- tryIO $ createLink src dest + ifM (catchBoolIO checklinked) + ( catchBoolIO $ not <$> checkInsaneLustre dest + , return False + ) + Left _ -> catchBoolIO $ do + fd <- openFd dest WriteOnly + (Just $ combineModes readModes) + (defaultFileFlags {exclusive = True}) + h <- fdToHandle fd + readFile src >>= hPutStr h + hClose h + return True where checklinked = do x <- getSymbolicLinkStatus src diff --git a/doc/forum/git_annex_init_timeout/comment_2_bf15b686b07c5e6e95796affa497a541._comment b/doc/forum/git_annex_init_timeout/comment_2_bf15b686b07c5e6e95796affa497a541._comment new file mode 100644 index 0000000000..c7f39ae530 --- /dev/null +++ b/doc/forum/git_annex_init_timeout/comment_2_bf15b686b07c5e6e95796affa497a541._comment @@ -0,0 +1,13 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 2""" + date="2017-02-10T18:52:59Z" + content=""" +I was able to reproduce the problem with a FAT filesystem +mounted on Linux, if I manually enabled annex.pidlock +before git-annex init. Hard linking does not work on FAT, so that +matches my earlier guess. + +I've committed a fix for this, so try again with a recent autobuild of +git-annex and it will probably fix your problem. +"""]]