info: Improve cleanup of stale transfer info files.

In my git-annex repos, I found some stale transfer info files
without lock files.

Pass a mode to tryLockExclusive, so it will create the lock file if
not present, and so not fail to clean up such transfer info files.

Normally, transfer info files are accompanied by a lock file.
But, when alwaysRunTransfer is used, the locking can fail
and it will still write the transfer info file. Perhaps there are other
cases too? Note that mkProgressUpdater's meter
writes to the transfer info file too, and it might be possible for
that meter to fire after runTransfer has cleaned up.

This commit was sponsored by andrea rota.
This commit is contained in:
Joey Hess 2017-10-02 13:55:26 -04:00
parent a99cca6889
commit 3cd47f9978
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
3 changed files with 27 additions and 6 deletions

View file

@ -17,6 +17,7 @@ git-annex (6.20170926) UNRELEASED; urgency=medium
* Fix process and file descriptor leak that was exposed when
git-annex was built with ghc 8.2.1. Broke git-annex test on OSX
due to running out of FDs, and may have also leaked in other situations.
* info: Improve cleanup of stale transfer info files.
-- Joey Hess <id@joeyh.name> Thu, 28 Sep 2017 12:01:39 -0400

View file

@ -93,22 +93,23 @@ startTransferInfo afile = TransferInfo
checkTransfer :: Transfer -> Annex (Maybe TransferInfo)
checkTransfer t = do
tfile <- fromRepo $ transferFile t
let lck = transferLockFile tfile
let cleanstale = do
void $ tryIO $ removeFile tfile
void $ tryIO $ removeFile $ transferLockFile tfile
void $ tryIO $ removeFile lck
#ifndef mingw32_HOST_OS
let lck = transferLockFile tfile
v <- getLockStatus lck
case v of
StatusLockedBy pid -> liftIO $ catchDefaultIO Nothing $
readTransferInfoFile (Just pid) tfile
StatusNoLockFile -> return Nothing
StatusUnLocked -> do
_ -> do
-- Take a non-blocking lock while deleting
-- the stale lock file. Ignore failure
-- due to permissions problems, races, etc.
void $ tryIO $ do
r <- tryLockExclusive Nothing lck
mode <- annexFileMode
let lck = transferLockFile tfile
r <- tryLockExclusive (Just mode) lck
case r of
Just lockhandle -> liftIO $ do
cleanstale
@ -116,7 +117,7 @@ checkTransfer t = do
_ -> noop
return Nothing
#else
v <- liftIO $ lockShared $ transferLockFile tfile
v <- liftIO $ lockShared lck
liftIO $ case v of
Nothing -> catchDefaultIO Nothing $
readTransferInfoFile Nothing tfile

View file

@ -0,0 +1,19 @@
[[!comment format=mdwn
username="joey"
subject="""comment 3"""
date="2017-10-02T16:55:59Z"
content="""
It's fine to delete .git/annex/transfer/ at any time.
Those files are used to make `git annex info` (and the webapp) be able to
show what transfers are in progress. Normally they're cleaned up when a
transfer finishes; if you interrupt git-annex they will be left behind.
Running `git annex info` is also supposed to clean up the stale transfer
info files, but it was broken -- now fixed.
The only time you get files in .git/annex/bad/ is when fsck finds a file
got corrupted somehow and moves its content there. It's fine to delete
those unless you were planning to recover or examine the corrupted file in
some way.
"""]]