decorate openTempFile errors with the template name

This is to track down what file in .git/annex/ is being written to via a
temp file when the repository is read-only.

Sponsored-by: Dartmouth College's Datalad project
This commit is contained in:
Joey Hess 2021-08-30 13:05:02 -04:00
parent 837116ef1e
commit e853ef3095
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 32 additions and 9 deletions

View file

@ -84,6 +84,7 @@ import Annex.Branch.Transitions
import qualified Annex
import Annex.Hook
import Utility.Directory.Stream
import Utility.Tmp
import qualified Utility.RawFilePath as R
{- Name of the branch that is used to store git-annex's information. -}
@ -596,7 +597,7 @@ stageJournal jl commitindex = withIndex $ withOtherTmp $ \tmpdir -> do
mapM_ (removeFile . (dir </>)) stagedfs
hClose jlogh
removeWhenExistsWith (R.removeLink) (toRawFilePath jlogf)
openjlog tmpdir = liftIO $ openTempFile tmpdir "jlog"
openjlog tmpdir = liftIO $ openTmpFileIn tmpdir "jlog"
{- This is run after the refs have been merged into the index,
- but before the result is committed to the branch.

View file

@ -110,7 +110,7 @@ lockDown' cfg file = tryNonAsync $ ifM crippledFileSystem
withhardlink tmpdir = do
setperms
withTSDelta $ \delta -> liftIO $ do
(tmpfile, h) <- openTempFile (fromRawFilePath tmpdir) $
(tmpfile, h) <- openTmpFileIn (fromRawFilePath tmpdir) $
relatedTemplate $ "ingest-" ++ takeFileName file
hClose h
removeWhenExistsWith R.removeLink (toRawFilePath tmpfile)

View file

@ -33,6 +33,7 @@ import Utility.Hash
import Utility.FileSystemEncoding
import Utility.Env
import Utility.Env.Set
import Utility.Tmp
import qualified Utility.LockFile.Posix as Posix
import System.IO
@ -143,7 +144,7 @@ tryLock lockfile = do
where
go abslockfile sidelock = do
let abslockfile' = fromRawFilePath abslockfile
(tmp, h) <- openTempFile (takeDirectory abslockfile') "locktmp"
(tmp, h) <- openTmpFileIn (takeDirectory abslockfile') "locktmp"
let tmp' = toRawFilePath tmp
setFileMode tmp' (combineModes readModes)
hPutStr h . show =<< mkPidLock

View file

@ -14,6 +14,7 @@ module Utility.Tmp (
withTmpFile,
withTmpFileIn,
relatedTemplate,
openTmpFileIn,
) where
import System.IO
@ -21,6 +22,7 @@ import System.FilePath
import System.Directory
import Control.Monad.IO.Class
import System.PosixCompat.Files hiding (removeLink)
import System.IO.Error
import Utility.Exception
import Utility.FileSystemEncoding
@ -28,6 +30,18 @@ import Utility.FileMode
type Template = String
{- This is the same as openTempFile, except when there is an
- error, it displays the template as well as the directory,
- to help identify what call was responsible.
-}
openTmpFileIn :: FilePath -> String -> IO (FilePath, Handle)
openTmpFileIn dir template = openTempFile dir template
`catchIO` decoraterrror
where
decoraterrror e = throwM $
let loc = ioeGetLocation e ++ " template " ++ template
in annotateIOError e loc Nothing Nothing
{- Runs an action like writeFile, writing to a temp file first and
- then moving it into place. The temp file is stored in the same
- directory as the final file to avoid cross-device renames.
@ -43,7 +57,7 @@ viaTmp a file content = bracketIO setup cleanup use
template = relatedTemplate (base ++ ".tmp")
setup = do
createDirectoryIfMissing True dir
openTempFile dir template
openTmpFileIn dir template
cleanup (tmpfile, h) = do
_ <- tryIO $ hClose h
tryIO $ removeFile tmpfile
@ -73,7 +87,7 @@ withTmpFile template a = do
withTmpFileIn :: (MonadIO m, MonadMask m) => FilePath -> Template -> (FilePath -> Handle -> m a) -> m a
withTmpFileIn tmpdir template a = bracket create remove use
where
create = liftIO $ openTempFile tmpdir template
create = liftIO $ openTmpFileIn tmpdir template
remove (name, h) = liftIO $ do
hClose h
catchBoolIO (removeFile name >> return True)

View file

@ -3,11 +3,18 @@
subject="""comment 3"""
date="2021-08-30T16:24:52Z"
content="""
reversion in [[!commit f46e4c9b7c]], which reversed some logic and made
database reads be treated as database writes, so they failed on permission
denied, rather than the right behavior of returning DbUnavailable. Fixed that.
keysdb error was a reversion in [[!commit f46e4c9b7c]], which reversed some
logic and made database reads be treated as database writes, so it failed
on permission denied, rather than the right behavior of returning
DbUnavailable when it cannot read or the database does not exist yet.
Fixed that. It seems to work for me now, both get and drop, and over ssh or
direct access to the readonly repository.
I have not been able to reproduce the other error involving
opening a temp file. All I can tell from the message is that it's writing
to some file in .git/annex via a temp file in the same directory.
to some file in .git/annex via a temp file in the same directory, but
I don't know what file it is trying to write. I've made a change that
will include more information in that error message. So either update
your build of git-annex, or find a better reproduction recipe for that..
"""]]