pid locking configuration and abstraction layer for git-annex
(not actually used anywhere yet)
This commit is contained in:
parent
77b490bfba
commit
aa4192aea6
7 changed files with 131 additions and 1 deletions
17
Annex/LockPool.hs
Normal file
17
Annex/LockPool.hs
Normal file
|
@ -0,0 +1,17 @@
|
|||
{- Wraps Utility.LockPool, making pid locks be used when git-annex is so
|
||||
- configured.
|
||||
-
|
||||
- Copyright 2015 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- Licensed under the GNU GPL version 3 or higher.
|
||||
-}
|
||||
|
||||
{-# LANGUAGE CPP #-}
|
||||
|
||||
module Annex.LockPool (module X) where
|
||||
|
||||
#ifndef mingw32_HOST_OS
|
||||
import Annex.LockPool.PosixOrPid as X
|
||||
#else
|
||||
import Utility.LockPool.Windows as X
|
||||
#endif
|
74
Annex/LockPool/PosixOrPid.hs
Normal file
74
Annex/LockPool/PosixOrPid.hs
Normal file
|
@ -0,0 +1,74 @@
|
|||
{- Wraps Utility.LockPool, making pid locks be used when git-annex is so
|
||||
- configured.
|
||||
-
|
||||
- Copyright 2015 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- Licensed under the GNU GPL version 3 or higher.
|
||||
-}
|
||||
|
||||
module Annex.LockPool.PosixOrPid where
|
||||
|
||||
import Common.Annex
|
||||
import qualified Annex
|
||||
import qualified Utility.LockPool.Posix as Posix
|
||||
import qualified Utility.LockPool.PidLock as Pid
|
||||
import Utility.LockFile.Posix (openLockFile)
|
||||
import Utility.LockPool.STM (LockFile)
|
||||
import Utility.LockPool.LockHandle
|
||||
import Utility.LockFile.LockStatus
|
||||
|
||||
import System.Posix
|
||||
|
||||
lockShared :: Maybe FileMode -> LockFile -> Annex LockHandle
|
||||
lockShared m f = pidLock m f $ Posix.lockShared m f
|
||||
|
||||
lockExclusive :: Maybe FileMode -> LockFile -> Annex LockHandle
|
||||
lockExclusive m f = pidLock m f $ Posix.lockExclusive m f
|
||||
|
||||
tryLockShared :: Maybe FileMode -> LockFile -> Annex (Maybe LockHandle)
|
||||
tryLockShared m f = tryPidLock m f $ Posix.tryLockShared m f
|
||||
|
||||
tryLockExclusive :: Maybe FileMode -> LockFile -> Annex (Maybe LockHandle)
|
||||
tryLockExclusive m f = tryPidLock m f $ Posix.tryLockExclusive m f
|
||||
|
||||
checkLocked :: LockFile -> Annex (Maybe Bool)
|
||||
checkLocked f = Posix.checkLocked f
|
||||
`pidLockCheck` Pid.checkLocked
|
||||
|
||||
getLockStatus :: LockFile -> Annex LockStatus
|
||||
getLockStatus f = Posix.getLockStatus f
|
||||
`pidLockCheck` Pid.getLockStatus
|
||||
|
||||
pidLockFile :: Annex (Maybe FilePath)
|
||||
pidLockFile = ifM (annexPidLock <$> Annex.getGitConfig)
|
||||
( Just <$> fromRepo gitAnnexPidLockFile
|
||||
, pure Nothing
|
||||
)
|
||||
|
||||
pidLockCheck :: IO a -> (LockFile -> IO a) -> Annex a
|
||||
pidLockCheck posixcheck pidcheck =
|
||||
liftIO . maybe posixcheck pidcheck =<< pidLockFile
|
||||
|
||||
pidLock :: Maybe FileMode -> LockFile -> IO LockHandle -> Annex LockHandle
|
||||
pidLock m f posixlock = go =<< pidLockFile
|
||||
where
|
||||
go Nothing = liftIO posixlock
|
||||
go (Just pidlock) = do
|
||||
timeout <- annexPidLockTimeout <$> Annex.getGitConfig
|
||||
liftIO $ do
|
||||
dummyPosixLock m f
|
||||
Pid.waitLock timeout pidlock
|
||||
|
||||
tryPidLock :: Maybe FileMode -> LockFile -> IO (Maybe LockHandle) -> Annex (Maybe LockHandle)
|
||||
tryPidLock m f posixlock = liftIO . go =<< pidLockFile
|
||||
where
|
||||
go Nothing = posixlock
|
||||
go (Just pidlock) = do
|
||||
dummyPosixLock m f
|
||||
Pid.tryLock pidlock
|
||||
|
||||
-- The posix lock file is created even when using pid locks, in order to
|
||||
-- avoid complicating any code that might expect to be able to see that
|
||||
-- lock file.
|
||||
dummyPosixLock :: Maybe FileMode -> LockFile -> IO ()
|
||||
dummyPosixLock m f = closeFd =<< openLockFile ReadLock m f
|
|
@ -51,6 +51,7 @@ module Locations (
|
|||
gitAnnexViewLog,
|
||||
gitAnnexIgnoredRefs,
|
||||
gitAnnexPidFile,
|
||||
gitAnnexPidLockFile,
|
||||
gitAnnexDaemonStatusFile,
|
||||
gitAnnexLogFile,
|
||||
gitAnnexFuzzTestLogFile,
|
||||
|
@ -334,6 +335,10 @@ gitAnnexIgnoredRefs r = gitAnnexDir r </> "ignoredrefs"
|
|||
gitAnnexPidFile :: Git.Repo -> FilePath
|
||||
gitAnnexPidFile r = gitAnnexDir r </> "daemon.pid"
|
||||
|
||||
{- Pid lock file for pidlock mode -}
|
||||
gitAnnexPidLockFile :: Git.Repo -> FilePath
|
||||
gitAnnexPidLockFile r = gitAnnexDir r </> "pidlock"
|
||||
|
||||
{- Status file for daemon mode. -}
|
||||
gitAnnexDaemonStatusFile :: Git.Repo -> FilePath
|
||||
gitAnnexDaemonStatusFile r = gitAnnexDir r </> "daemon.status"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{- git-annex configuration
|
||||
-
|
||||
- Copyright 2012-2014 Joey Hess <id@joeyh.name>
|
||||
- Copyright 2012-2015 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- Licensed under the GNU GPL version 3 or higher.
|
||||
-}
|
||||
|
@ -26,6 +26,7 @@ import Types.Difference
|
|||
import Types.RefSpec
|
||||
import Utility.HumanTime
|
||||
import Utility.Gpg (GpgCmd, mkGpgCmd)
|
||||
import Utility.ThreadScheduler (Seconds(..))
|
||||
|
||||
{- Main git-annex settings. Each setting corresponds to a git-config key
|
||||
- such as annex.foo -}
|
||||
|
@ -62,6 +63,8 @@ data GitConfig = GitConfig
|
|||
, annexDifferences :: Differences
|
||||
, annexUsedRefSpec :: Maybe RefSpec
|
||||
, annexVerify :: Bool
|
||||
, annexPidLock :: Bool
|
||||
, annexPidLockTimeout :: Seconds
|
||||
, coreSymlinks :: Bool
|
||||
, coreSharedRepository :: SharedRepository
|
||||
, gcryptId :: Maybe String
|
||||
|
@ -105,6 +108,9 @@ extractGitConfig r = GitConfig
|
|||
, annexUsedRefSpec = either (const Nothing) Just . parseRefSpec
|
||||
=<< getmaybe (annex "used-refspec")
|
||||
, annexVerify = getbool (annex "verify") True
|
||||
, annexPidLock = getbool (annex "pidlock") False
|
||||
, annexPidLockTimeout = Seconds $ fromMaybe 300 $
|
||||
getmayberead (annex "pidlocktimeout")
|
||||
, coreSymlinks = getbool "core.symlinks" True
|
||||
, coreSharedRepository = getSharedRepository r
|
||||
, gcryptId = getmaybe "core.gcrypt-id"
|
||||
|
|
|
@ -16,6 +16,8 @@ module Utility.LockFile.Posix (
|
|||
LockStatus(..),
|
||||
dropLock,
|
||||
checkSaneLock,
|
||||
LockRequest(..),
|
||||
openLockFile,
|
||||
) where
|
||||
|
||||
import Utility.Exception
|
||||
|
|
2
debian/changelog
vendored
2
debian/changelog
vendored
|
@ -27,6 +27,8 @@ git-annex (5.20151102.2) UNRELEASED; urgency=medium
|
|||
dead repo.
|
||||
* assistant: Pass ssh-options through 3 more git pull/push calls
|
||||
that were missed before.
|
||||
* Added annex.pidlock and annex.pidlocktimeout configuration to support
|
||||
filesystems where POSIX fcntl locks cannot be used.
|
||||
|
||||
-- Joey Hess <id@joeyh.name> Wed, 04 Nov 2015 12:50:20 -0400
|
||||
|
||||
|
|
|
@ -965,6 +965,30 @@ Here are all the supported configuration settings.
|
|||
which does not support symbolic links, or hard links, or unix permissions.
|
||||
This is automatically probed by "git annex init".
|
||||
|
||||
* `annex.pidlock`
|
||||
|
||||
Normally, git-annex uses fine-grained lock files to allow multiple
|
||||
processes to run concurrently without getting in each others' way.
|
||||
That works great, unless you are using git-annex on a filesystem that
|
||||
does not support POSIX fcntl locks. This is sometimes the case when
|
||||
using NFS or Lustre filesystems.
|
||||
|
||||
To support such situations, you can set annex.pidlock to true, and it
|
||||
will fall back to a single top-level pid file lock.
|
||||
|
||||
(Although, often, you'd really be better off fixing your networked
|
||||
filesystem configuration to support POSIX locks..)
|
||||
|
||||
* `annex.pidlocktimeout`
|
||||
|
||||
When using pid lock files, it's possible for a stale lock file to get
|
||||
left behind by previous run of git-annex that crashed or was interrupted.
|
||||
This is mostly avoided, but can occur especially when using a network
|
||||
file system.
|
||||
|
||||
git-annex will wait up to this many seconds for the pid lock
|
||||
file to go away, and will then abort if it cannot continue. Default: 300
|
||||
|
||||
* `remote.<name>.annex-cost`
|
||||
|
||||
When determining which repository to
|
||||
|
|
Loading…
Reference in a new issue