From 220d54ffbd0d3d3bba8662d1964c02fe1a44cb38 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 13 Nov 2013 14:27:17 -0400 Subject: assistant: Notice on startup when the index file is corrupt, and auto-repair. --- Assistant/Threads/SanityChecker.hs | 12 ++++++++++++ Assistant/Threads/Watcher.hs | 7 +++++-- Assistant/Types/DaemonStatus.hs | 3 +++ 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'Assistant') diff --git a/Assistant/Threads/SanityChecker.hs b/Assistant/Threads/SanityChecker.hs index b03298510..585a85cdf 100644 --- a/Assistant/Threads/SanityChecker.hs +++ b/Assistant/Threads/SanityChecker.hs @@ -25,8 +25,10 @@ import Utility.Batch import Utility.NotificationBroadcaster import Config import Utility.HumanTime +import Git.Repair import Data.Time.Clock.POSIX +import qualified Data.Set as S {- This thread runs once at startup, and most other threads wait for it - to finish. (However, the webapp thread does not, to prevent the UI @@ -36,6 +38,16 @@ sanityCheckerStartupThread startupdelay = namedThreadUnchecked "SanityCheckerSta {- Stale git locks can prevent commits from happening, etc. -} void $ repairStaleGitLocks =<< liftAnnex gitRepo + {- A corrupt index file can prevent the assistant from working at + - all, so detect and repair. -} + unlessM (liftAnnex $ inRepo $ checkIndex S.empty) $ do + debug ["corrupt index found at startup; removing"] + liftAnnex $ inRepo nukeIndex + {- Normally the startup scan avoids re-staging files, + - but with the index deleted, everything needs to be + - restaged. -} + modifyDaemonStatus_ $ \s -> s { forceRestage = True } + {- If there's a startup delay, it's done here. -} liftIO $ maybe noop (threadDelaySeconds . Seconds . fromIntegral . durationSeconds) startupdelay diff --git a/Assistant/Threads/Watcher.hs b/Assistant/Threads/Watcher.hs index 3eedbe145..6a56eadbb 100644 --- a/Assistant/Threads/Watcher.hs +++ b/Assistant/Threads/Watcher.hs @@ -200,6 +200,9 @@ onAdd matcher file filestatus add matcher file | otherwise = noChange +shouldRestage :: DaemonStatus -> Bool +shouldRestage ds = scanComplete ds || forceRestage ds + {- In direct mode, add events are received for both new files, and - modified existing files. -} @@ -214,7 +217,7 @@ onAddDirect symlinkssupported matcher file fs = do - really modified, but it might have - just been deleted and been put back, - so it symlink is restaged to make sure. -} - ( ifM (scanComplete <$> getDaemonStatus) + ( ifM (shouldRestage <$> getDaemonStatus) ( do link <- liftAnnex $ inRepo $ gitAnnexLink file key addLink file link (Just key) @@ -286,7 +289,7 @@ onAddSymlink' linktarget mk isdirect file filestatus = go mk - links too.) -} ensurestaged (Just link) daemonstatus - | scanComplete daemonstatus = addLink file link mk + | shouldRestage daemonstatus = addLink file link mk | otherwise = case filestatus of Just s | not (afterLastDaemonRun (statusChangeTime s) daemonstatus) -> noChange diff --git a/Assistant/Types/DaemonStatus.hs b/Assistant/Types/DaemonStatus.hs index a1a0d64dc..5d2f5bb37 100644 --- a/Assistant/Types/DaemonStatus.hs +++ b/Assistant/Types/DaemonStatus.hs @@ -28,6 +28,8 @@ data DaemonStatus = DaemonStatus { startedThreads :: M.Map ThreadName (Async (), IO ()) -- False when the daemon is performing its startup scan , scanComplete :: Bool + -- True when all files should be restaged. + , forceRestage :: Bool -- Time when a previous process of the daemon was running ok , lastRunning :: Maybe POSIXTime -- True when the daily sanity checker is running @@ -81,6 +83,7 @@ newDaemonStatus :: IO DaemonStatus newDaemonStatus = DaemonStatus <$> pure M.empty <*> pure False + <*> pure False <*> pure Nothing <*> pure False <*> pure Nothing -- cgit v1.2.3