summaryrefslogtreecommitdiff
path: root/Command/Fsck.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2015-02-17 13:04:22 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2015-02-17 13:30:24 -0400
commitc18aca6a6a1673d17467e25eb5c900f824c8231c (patch)
tree0ef32f822433fc6a6306db0b31640588224e19e8 /Command/Fsck.hs
parentd14b4c2a607409fbec81fedd2cc89ee77ba6a62e (diff)
avoid crash when starting fsck --incremental when one is already running
Turns out sqlite does not like having its database deleted out from underneath it. It might suffice to empty the table, but I would rather start each fsck over with a new database, so I added a lock file, and running incremental fscks use a shared lock. This leaves one concurrency bug left; running two concurrent fsck --more will lead to: "SQLite3 returned ErrorBusy while attempting to perform step." and one or both will fail. This is a concurrent writers problem.
Diffstat (limited to 'Command/Fsck.hs')
-rw-r--r--Command/Fsck.hs8
1 files changed, 5 insertions, 3 deletions
diff --git a/Command/Fsck.hs b/Command/Fsck.hs
index 9dba21dbf..799396a10 100644
--- a/Command/Fsck.hs
+++ b/Command/Fsck.hs
@@ -72,7 +72,7 @@ seek ps = do
(\k -> startKey i k =<< getNumCopies)
(withFilesInGit $ whenAnnexed $ start from i)
ps
- withFsckDb i (liftIO . FsckDb.closeDb)
+ withFsckDb i FsckDb.closeDb
getIncremental :: Annex Incremental
getIncremental = do
@@ -91,8 +91,10 @@ getIncremental = do
where
startIncremental = do
recordStartTime
- FsckDb.newPass
- StartIncremental <$> FsckDb.openDb
+ ifM FsckDb.newPass
+ ( StartIncremental <$> FsckDb.openDb
+ , error "Cannot start a new --incremental fsck pass; another fsck process is already running."
+ )
contIncremental = ContIncremental <$> FsckDb.openDb
checkschedule Nothing = error "bad --incremental-schedule value"