diff options
author | Joey Hess <joeyh@joeyh.name> | 2015-02-17 13:04:22 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2015-02-17 13:30:24 -0400 |
commit | c18aca6a6a1673d17467e25eb5c900f824c8231c (patch) | |
tree | 0ef32f822433fc6a6306db0b31640588224e19e8 /Command/Fsck.hs | |
parent | d14b4c2a607409fbec81fedd2cc89ee77ba6a62e (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.hs | 8 |
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" |