2015-10-08 20:55:11 +00:00
|
|
|
{- git-annex numcopies types
|
2014-01-21 20:08:19 +00:00
|
|
|
-
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
- Copyright 2014-2024 Joey Hess <id@joeyh.name>
|
2014-01-21 20:08:19 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2014-01-21 20:08:19 +00:00
|
|
|
-}
|
|
|
|
|
2015-10-08 21:58:32 +00:00
|
|
|
module Types.NumCopies (
|
2022-03-28 19:19:52 +00:00
|
|
|
NumCopies,
|
|
|
|
configuredNumCopies,
|
2015-10-08 21:58:32 +00:00
|
|
|
fromNumCopies,
|
2022-03-28 19:19:52 +00:00
|
|
|
MinCopies,
|
|
|
|
configuredMinCopies,
|
2021-01-06 18:11:08 +00:00
|
|
|
fromMinCopies,
|
2015-10-08 21:58:32 +00:00
|
|
|
VerifiedCopy(..),
|
|
|
|
checkVerifiedCopy,
|
|
|
|
invalidateVerifiedCopy,
|
|
|
|
strongestVerifiedCopy,
|
|
|
|
deDupVerifiedCopies,
|
|
|
|
mkVerifiedCopy,
|
|
|
|
invalidatableVerifiedCopy,
|
2015-10-09 14:30:22 +00:00
|
|
|
withVerifiedCopy,
|
2015-10-09 15:09:46 +00:00
|
|
|
isSafeDrop,
|
|
|
|
SafeDropProof,
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
safeDropProofEndTime,
|
2015-10-09 15:09:46 +00:00
|
|
|
mkSafeDropProof,
|
2015-10-09 19:48:02 +00:00
|
|
|
ContentRemovalLock(..),
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
p2pDefaultLockContentRetentionDuration,
|
2015-10-08 21:58:32 +00:00
|
|
|
) where
|
2014-01-21 20:08:19 +00:00
|
|
|
|
2015-10-08 20:55:11 +00:00
|
|
|
import Types.UUID
|
2015-10-09 19:48:02 +00:00
|
|
|
import Types.Key
|
2015-10-09 14:30:22 +00:00
|
|
|
import Utility.Exception (bracketIO)
|
2015-10-09 20:55:41 +00:00
|
|
|
import Utility.Monad
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
import Utility.HumanTime
|
2015-10-08 20:55:11 +00:00
|
|
|
|
|
|
|
import qualified Data.Map as M
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
import Data.Either
|
2015-10-08 21:58:32 +00:00
|
|
|
import Control.Concurrent.MVar
|
2015-10-09 14:30:22 +00:00
|
|
|
import Control.Monad.Catch (MonadMask)
|
|
|
|
import Control.Monad.IO.Class (MonadIO)
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
import Data.Time.Clock.POSIX (POSIXTime)
|
2015-10-08 20:55:11 +00:00
|
|
|
|
2014-01-21 20:08:19 +00:00
|
|
|
newtype NumCopies = NumCopies Int
|
2015-10-09 17:47:19 +00:00
|
|
|
deriving (Ord, Eq, Show)
|
2014-01-21 20:08:19 +00:00
|
|
|
|
2022-03-28 19:19:52 +00:00
|
|
|
-- Smart constructor; prevent configuring numcopies to 0 which would
|
|
|
|
-- cause data loss.
|
|
|
|
configuredNumCopies :: Int -> NumCopies
|
|
|
|
configuredNumCopies n
|
|
|
|
| n > 0 = NumCopies n
|
|
|
|
| otherwise = NumCopies 1
|
|
|
|
|
2014-01-21 20:08:19 +00:00
|
|
|
fromNumCopies :: NumCopies -> Int
|
|
|
|
fromNumCopies (NumCopies n) = n
|
2015-10-08 20:55:11 +00:00
|
|
|
|
2021-01-06 18:11:08 +00:00
|
|
|
newtype MinCopies = MinCopies Int
|
|
|
|
deriving (Ord, Eq, Show)
|
|
|
|
|
2022-03-28 19:19:52 +00:00
|
|
|
configuredMinCopies :: Int -> MinCopies
|
|
|
|
configuredMinCopies n
|
|
|
|
| n > 0 = MinCopies n
|
|
|
|
| otherwise = MinCopies 1
|
|
|
|
|
2021-01-06 18:11:08 +00:00
|
|
|
fromMinCopies :: MinCopies -> Int
|
|
|
|
fromMinCopies (MinCopies n) = n
|
|
|
|
|
2015-10-09 19:48:02 +00:00
|
|
|
-- Indicates that a key's content is exclusively
|
|
|
|
-- locked locally, pending removal.
|
|
|
|
newtype ContentRemovalLock = ContentRemovalLock Key
|
|
|
|
deriving (Show)
|
|
|
|
|
2015-10-08 21:58:32 +00:00
|
|
|
-- A verification that a copy of a key exists in a repository.
|
2015-10-08 20:55:11 +00:00
|
|
|
data VerifiedCopy
|
|
|
|
{- Represents a recent verification that a copy of an
|
|
|
|
- object exists in a repository with the given UUID. -}
|
2015-10-08 22:32:31 +00:00
|
|
|
= RecentlyVerifiedCopy V
|
|
|
|
{- Use when a repository cannot be accessed, but it's
|
|
|
|
- a trusted repository, which is on record as containing a key
|
|
|
|
- and is presumably not going to lose its copy. -}
|
|
|
|
| TrustedCopy V
|
2015-10-08 20:55:11 +00:00
|
|
|
{- The strongest proof of the existence of a copy.
|
|
|
|
- Until its associated action is called to unlock it,
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
- or connection with a remote repository is lost,
|
2015-10-08 20:55:11 +00:00
|
|
|
- the copy is locked in the repository and is guaranteed
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
- not to be removed by any git-annex process. Use
|
|
|
|
- checkVerifiedCopy to detect loss of connection. -}
|
2015-10-09 19:01:16 +00:00
|
|
|
| LockedCopy V
|
2015-10-08 21:58:32 +00:00
|
|
|
deriving (Show)
|
2015-10-08 20:55:11 +00:00
|
|
|
|
2015-10-09 14:30:22 +00:00
|
|
|
data V = V
|
|
|
|
{ _getUUID :: UUID
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
, _checkVerifiedCopy :: IO (Either POSIXTime Bool)
|
2015-10-09 14:30:22 +00:00
|
|
|
, _invalidateVerifiedCopy :: IO ()
|
|
|
|
}
|
|
|
|
|
|
|
|
instance Show V where
|
|
|
|
show v = show (_getUUID v)
|
|
|
|
|
2015-10-08 20:55:11 +00:00
|
|
|
instance ToUUID VerifiedCopy where
|
2015-10-08 21:58:32 +00:00
|
|
|
toUUID = _getUUID . toV
|
|
|
|
|
|
|
|
toV :: VerifiedCopy -> V
|
|
|
|
toV (TrustedCopy v) = v
|
|
|
|
toV (RecentlyVerifiedCopy v) = v
|
2015-10-09 19:01:16 +00:00
|
|
|
toV (LockedCopy v) = v
|
2015-10-08 20:55:11 +00:00
|
|
|
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
-- Checks that the VerifiedCopy is still valid.
|
|
|
|
--
|
|
|
|
-- Invalidation of the VerifiedCopy will make this return False.
|
|
|
|
--
|
|
|
|
-- When the key is being kept locked by a connection to a remote
|
|
|
|
-- repository, a detected loss of connection will make this
|
|
|
|
-- return False.
|
|
|
|
--
|
|
|
|
-- When the connection could possibly break without being detected
|
|
|
|
-- immediately, this will return a POSIXTime that is how long the
|
|
|
|
-- content is guaranteed to remain locked on the remote even if the
|
|
|
|
-- connection has broken.
|
|
|
|
checkVerifiedCopy :: VerifiedCopy -> IO (Either POSIXTime Bool)
|
2015-10-08 21:58:32 +00:00
|
|
|
checkVerifiedCopy = _checkVerifiedCopy . toV
|
|
|
|
|
|
|
|
invalidateVerifiedCopy :: VerifiedCopy -> IO ()
|
|
|
|
invalidateVerifiedCopy = _invalidateVerifiedCopy . toV
|
|
|
|
|
2015-10-08 20:55:11 +00:00
|
|
|
strongestVerifiedCopy :: VerifiedCopy -> VerifiedCopy -> VerifiedCopy
|
2015-10-09 19:01:16 +00:00
|
|
|
strongestVerifiedCopy a@(LockedCopy _) _ = a
|
|
|
|
strongestVerifiedCopy _ b@(LockedCopy _) = b
|
2015-10-08 22:32:31 +00:00
|
|
|
strongestVerifiedCopy a@(TrustedCopy _) _ = a
|
|
|
|
strongestVerifiedCopy _ b@(TrustedCopy _) = b
|
2015-10-08 21:58:32 +00:00
|
|
|
strongestVerifiedCopy a@(RecentlyVerifiedCopy _) _ = a
|
2015-10-08 20:55:11 +00:00
|
|
|
|
|
|
|
-- Retains stronger verifications over weaker for the same uuid.
|
|
|
|
deDupVerifiedCopies :: [VerifiedCopy] -> [VerifiedCopy]
|
|
|
|
deDupVerifiedCopies l = M.elems $
|
|
|
|
M.fromListWith strongestVerifiedCopy (zip (map toUUID l) l)
|
2015-10-08 21:58:32 +00:00
|
|
|
|
|
|
|
mkVerifiedCopy :: ToUUID u => (V -> VerifiedCopy) -> u -> VerifiedCopy
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
mkVerifiedCopy mk u = mk $ V (toUUID u) (return (Right True)) (return ())
|
2015-10-08 21:58:32 +00:00
|
|
|
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
invalidatableVerifiedCopy :: ToUUID u => (V -> VerifiedCopy) -> u -> IO (Either POSIXTime Bool) -> IO VerifiedCopy
|
2015-10-09 20:55:41 +00:00
|
|
|
invalidatableVerifiedCopy mk u check = do
|
2015-10-08 21:58:32 +00:00
|
|
|
v <- newEmptyMVar
|
|
|
|
let invalidate = do
|
|
|
|
_ <- tryPutMVar v ()
|
|
|
|
return ()
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
let check' = ifM (isEmptyMVar v)
|
|
|
|
( check
|
|
|
|
, pure (Right False)
|
|
|
|
)
|
2015-10-09 20:55:41 +00:00
|
|
|
return $ mk $ V (toUUID u) check' invalidate
|
2015-10-09 14:30:22 +00:00
|
|
|
|
|
|
|
-- Constructs a VerifiedCopy, and runs the action, ensuring that the
|
|
|
|
-- verified copy is invalidated when the action returns, or on error.
|
|
|
|
withVerifiedCopy
|
2016-01-27 13:50:33 +00:00
|
|
|
:: (MonadMask m, MonadIO m, ToUUID u)
|
2015-10-09 14:30:22 +00:00
|
|
|
=> (V -> VerifiedCopy)
|
|
|
|
-> u
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
-> IO (Either POSIXTime Bool)
|
2015-10-09 14:30:22 +00:00
|
|
|
-> (VerifiedCopy -> m a)
|
|
|
|
-> m a
|
2015-10-09 20:55:41 +00:00
|
|
|
withVerifiedCopy mk u check = bracketIO setup cleanup
|
2015-10-09 14:30:22 +00:00
|
|
|
where
|
2015-10-09 20:55:41 +00:00
|
|
|
setup = invalidatableVerifiedCopy mk u check
|
2015-10-09 14:30:22 +00:00
|
|
|
cleanup = invalidateVerifiedCopy
|
2015-10-09 15:09:46 +00:00
|
|
|
|
|
|
|
{- Check whether enough verification has been done of copies to allow
|
|
|
|
- dropping content safely.
|
|
|
|
-
|
2015-10-09 19:48:02 +00:00
|
|
|
- This is carefully balanced to prevent data loss when there are races
|
|
|
|
- between concurrent drops of the same content in different repos,
|
|
|
|
- without requiring impractical amounts of locking.
|
|
|
|
-
|
|
|
|
- In particular, concurrent drop races may cause the number of copies
|
2021-01-06 18:11:08 +00:00
|
|
|
- to fall below NumCopies, but it will never fall below MinCopies.
|
2015-10-09 19:48:02 +00:00
|
|
|
-}
|
2021-01-06 18:11:08 +00:00
|
|
|
isSafeDrop :: NumCopies -> MinCopies -> [VerifiedCopy] -> Maybe ContentRemovalLock -> Bool
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
isSafeDrop n m l lck = case safeDropAnalysis n m l lck of
|
|
|
|
UnsafeDrop -> False
|
|
|
|
SafeDrop -> True
|
|
|
|
SafeDropCheckTime -> True
|
|
|
|
|
|
|
|
data SafeDropAnalysis
|
|
|
|
= UnsafeDrop
|
|
|
|
| SafeDrop
|
|
|
|
| SafeDropCheckTime
|
|
|
|
|
|
|
|
safeDropAnalysis :: NumCopies -> MinCopies -> [VerifiedCopy] -> Maybe ContentRemovalLock -> SafeDropAnalysis
|
2015-10-09 19:48:02 +00:00
|
|
|
{- When a ContentRemovalLock is provided, the content is being
|
|
|
|
- dropped from the local repo. That lock will prevent other git repos
|
|
|
|
- that are concurrently dropping from using the local copy as a VerifiedCopy.
|
|
|
|
- So, no additional locking is needed; all we need is verifications
|
2021-04-27 17:37:03 +00:00
|
|
|
- of any kind of enough other copies of the content. -}
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
safeDropAnalysis (NumCopies n) (MinCopies m) l (Just (ContentRemovalLock _)) =
|
|
|
|
if length (deDupVerifiedCopies l) >= max n m
|
|
|
|
then SafeDrop
|
|
|
|
else UnsafeDrop
|
2015-10-09 19:48:02 +00:00
|
|
|
{- Dropping from a remote repo.
|
|
|
|
-
|
2021-01-06 18:11:08 +00:00
|
|
|
- To guarantee MinCopies is never violated, at least that many LockedCopy
|
|
|
|
- or TrustedCopy are required. A LockedCopy prevents races between
|
|
|
|
- concurrent drops from dropping the last copy, no matter what.
|
2015-10-09 15:09:46 +00:00
|
|
|
-
|
2021-01-06 18:11:08 +00:00
|
|
|
- The other copies required by NumCopies can be less strong verifications,
|
|
|
|
- like RecentlyVerifiedCopy. While those are subject to concurrent drop
|
|
|
|
- races, and so could be dropped all at once, causing NumCopies to be
|
|
|
|
- violated, this is the best that can be done without requiring that
|
2015-10-09 19:48:02 +00:00
|
|
|
- all special remotes support locking.
|
2015-10-09 15:09:46 +00:00
|
|
|
-}
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
safeDropAnalysis (NumCopies n) (MinCopies m) l Nothing
|
|
|
|
| n == 0 && m == 0 = SafeDrop
|
|
|
|
| length (deDupVerifiedCopies l) >= n
|
|
|
|
&& length (filter fullVerification l) >= m =
|
|
|
|
SafeDropCheckTime
|
|
|
|
| otherwise = UnsafeDrop
|
2015-10-09 15:09:46 +00:00
|
|
|
|
|
|
|
fullVerification :: VerifiedCopy -> Bool
|
2015-10-09 19:01:16 +00:00
|
|
|
fullVerification (LockedCopy _) = True
|
2015-10-09 15:09:46 +00:00
|
|
|
fullVerification (TrustedCopy _) = True
|
|
|
|
fullVerification (RecentlyVerifiedCopy _) = False
|
|
|
|
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
-- Content locked using the P2P protocol defaults to being retained,
|
|
|
|
-- still locked, for 10 minutes after a connection loss.
|
|
|
|
--
|
|
|
|
-- This is only the case since git-annex 10.20240704, but currently
|
|
|
|
-- this is used even for older remotes, to avoid a disruptive behavior
|
|
|
|
-- change when used with remotes running an old version of git-annex.
|
|
|
|
p2pDefaultLockContentRetentionDuration :: Duration
|
|
|
|
p2pDefaultLockContentRetentionDuration = Duration (60*10)
|
|
|
|
|
|
|
|
-- A proof that it's safe to drop an object.
|
|
|
|
--
|
|
|
|
-- It may only be safe up until a given POSIXTime.
|
|
|
|
data SafeDropProof = SafeDropProof NumCopies MinCopies [VerifiedCopy] (Maybe POSIXTime) (Maybe ContentRemovalLock)
|
2015-10-09 17:47:19 +00:00
|
|
|
deriving (Show)
|
2015-10-09 15:09:46 +00:00
|
|
|
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
safeDropProofEndTime :: SafeDropProof -> Maybe POSIXTime
|
|
|
|
safeDropProofEndTime (SafeDropProof _ _ _ t _) = t
|
|
|
|
|
2021-01-06 18:11:08 +00:00
|
|
|
-- Makes sure that none of the VerifiedCopies have become invalidated
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
-- before constructing the proof.
|
2021-01-06 18:11:08 +00:00
|
|
|
mkSafeDropProof :: NumCopies -> MinCopies -> [VerifiedCopy] -> Maybe ContentRemovalLock -> IO (Either [VerifiedCopy] SafeDropProof)
|
|
|
|
mkSafeDropProof need mincopies have removallock = do
|
toward SafeDropProof expiry checking
Added Maybe POSIXTime to SafeDropProof, which gets set when the proof is
based on a LockedCopy. If there are several LockedCopies, it uses the
closest expiry time. That is not optimal, it may be that the proof
expires based on one LockedCopy but another one has not expired. But
that seems unlikely to really happen, and anyway the user can just
re-run a drop if it fails due to expiry.
Pass the SafeDropProof to removeKey, which is responsible for checking
it for expiry in situations where that could be a problem. Which really
only means in Remote.Git.
Made Remote.Git check expiry when dropping from a local remote.
Checking expiry when dropping from a P2P remote is not yet implemented.
P2P.Protocol.remove has SafeDropProof plumbed through to it for that
purpose.
Fixing the remaining 2 build warnings should complete this work.
Note that the use of a POSIXTime here means that if the clock gets set
forward while git-annex is in the middle of a drop, it may say that
dropping took too long. That seems ok. Less ok is that if the clock gets
turned back a sufficient amount (eg 5 minutes), proof expiry won't be
noticed. It might be better to use the Monotonic clock, but that doesn't
advance when a laptop is suspended, and while there is the linux
Boottime clock, that is not available on other systems. Perhaps a
combination of POSIXTime and the Monotonic clock could detect laptop
suspension and also detect clock being turned back?
There is a potential future flag day where
p2pDefaultLockContentRetentionDuration is not assumed, but is probed
using the P2P protocol, and peers that don't support it can no longer
produce a LockedCopy. Until that happens, when git-annex is
communicating with older peers there is a risk of data loss when
a ssh connection closes during LOCKCONTENT.
2024-07-04 16:23:46 +00:00
|
|
|
l <- mapM checkVerifiedCopy have
|
|
|
|
let stillhave = map fst $
|
|
|
|
filter (either (const True) id . snd) (zip have l)
|
|
|
|
return $ case safeDropAnalysis need mincopies stillhave removallock of
|
|
|
|
SafeDrop -> Right $
|
|
|
|
SafeDropProof need mincopies stillhave Nothing removallock
|
|
|
|
SafeDropCheckTime -> Right $
|
|
|
|
let endtime = case lefts l of
|
|
|
|
[] -> Nothing
|
|
|
|
ts -> Just (minimum ts)
|
|
|
|
in SafeDropProof need mincopies stillhave endtime removallock
|
|
|
|
UnsafeDrop -> Left stillhave
|