From 96dc423e3974eea558d10167feda798e1d5fc60d Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 20 Aug 2014 12:01:45 -0400 Subject: [PATCH] When accessing a local remote, shut down git-cat-file processes afterwards, to ensure that remotes on removable media can be unmounted. Closes: #758630 This does mean that eg, copying multiple files to a local remote will become slightly slower, since it now restarts git-cat-file after each copy. Should not be significant slowdown. The reason git-cat-file is run on the remote at all is to update its location log. In order to add an item to it, it needs to get the current content of the log. Finding a way to avoid needing to do that would be a good path to avoiding this slowdown if it does become a problem somehow. This commit was sponsored by Evan Deaubl. --- Annex.hs | 6 ++++++ Annex/CatFile.hs | 9 +++++++++ Remote/Git.hs | 6 +++++- debian/changelog | 3 +++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Annex.hs b/Annex.hs index b915e852bc..a04bfd1bb1 100644 --- a/Annex.hs +++ b/Annex.hs @@ -15,6 +15,7 @@ module Annex ( eval, getState, changeState, + withState, setFlag, setField, setOutput, @@ -214,6 +215,11 @@ changeState modifier = do mvar <- ask liftIO $ modifyMVar_ mvar $ return . modifier +withState :: (AnnexState -> (AnnexState, b)) -> Annex b +withState modifier = do + mvar <- ask + liftIO $ modifyMVar mvar $ return . modifier + {- Sets a flag to True -} setFlag :: String -> Annex () setFlag flag = changeState $ \s -> diff --git a/Annex/CatFile.hs b/Annex/CatFile.hs index 2f8c430794..8b4d746e15 100644 --- a/Annex/CatFile.hs +++ b/Annex/CatFile.hs @@ -12,6 +12,7 @@ module Annex.CatFile ( catTree, catObjectDetails, catFileHandle, + catFileStop, catKey, catKeyFile, catKeyFileHEAD, @@ -71,6 +72,14 @@ catFileHandle = do Annex.changeState $ \s -> s { Annex.catfilehandles = m' } return h +{- Stops all running cat-files. Should only be run when it's known that + - nothing is using the handles, eg at shutdown. -} +catFileStop :: Annex () +catFileStop = do + m <- Annex.withState $ \s -> + (s { Annex.catfilehandles = M.empty }, Annex.catfilehandles s) + liftIO $ mapM_ Git.CatFile.catFileStop (M.elems m) + {- From the Sha or Ref of a symlink back to the key. - - Requires a mode witness, to guarantee that the file is a symlink. diff --git a/Remote/Git.hs b/Remote/Git.hs index 5416a5cdac..db5b2fbd0a 100644 --- a/Remote/Git.hs +++ b/Remote/Git.hs @@ -51,6 +51,7 @@ import qualified Remote.Helper.Ssh as Ssh import qualified Remote.GCrypt import Config.Files import Creds +import Annex.CatFile import Control.Concurrent import Control.Concurrent.MSampleVar @@ -500,6 +501,8 @@ repairRemote r a = return $ do {- Runs an action from the perspective of a local remote. - - The AnnexState is cached for speed and to avoid resource leaks. + - However, catFileStop is called to avoid git-cat-file processes hanging + - around on removable media. - - The repository's git-annex branch is not updated, as an optimisation. - No caller of onLocal can query data from the branch and be ensured @@ -520,7 +523,8 @@ onLocal r a = do cache st = Annex.changeState $ \s -> s { Annex.remoteannexstate = M.insert (uuid r) st (Annex.remoteannexstate s) } go st a' = do - (ret, st') <- liftIO $ Annex.run st a' + (ret, st') <- liftIO $ Annex.run st $ + catFileStop `after` a' cache st' return ret diff --git a/debian/changelog b/debian/changelog index 2e22006969..9e5dfcf8c4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,9 @@ git-annex (5.20140818) UNRELEASED; urgency=medium * Make --help work when not in a git repository. Closes: #758592 * Ensure that all lock fds are close-on-exec, fixing various problems with them being inherited by child processes such as git commands. + * When accessing a local remote, shut down git-cat-file processes + afterwards, to ensure that remotes on removable media can be unmounted. + Closes: #758630 -- Joey Hess Tue, 19 Aug 2014 12:52:41 -0400