Browse Source

Merge pull request #2163 from calmh/dbrecover

Recover from 'corrupted or incomplete CURRENT file' etc
Audrius Butkevicius 10 years ago
parent
commit
b6b6375f70
1 changed files with 27 additions and 1 deletions
  1. 27 1
      cmd/syncthing/main.go

+ 27 - 1
cmd/syncthing/main.go

@@ -591,9 +591,19 @@ func syncthingMain() {
 
 	dbFile := locations[locDatabase]
 	ldb, err := leveldb.OpenFile(dbFile, dbOpts())
-	if err != nil && errors.IsCorrupted(err) {
+	if leveldbIsCorrupted(err) {
 		ldb, err = leveldb.RecoverFile(dbFile, dbOpts())
 	}
+	if leveldbIsCorrupted(err) {
+		// The database is corrupted, and we've tried to recover it but it
+		// didn't work. At this point there isn't much to do beyond dropping
+		// the database and reindexing...
+		l.Infoln("Database corruption detected, unable to recover. Reinitializing...")
+		if err := resetDB(); err != nil {
+			l.Fatalln("Remove database:", err)
+		}
+		ldb, err = leveldb.OpenFile(dbFile, dbOpts())
+	}
 	if err != nil {
 		l.Fatalln("Cannot open database:", err, "- Is another copy of Syncthing already running?")
 	}
@@ -1105,3 +1115,19 @@ func checkShortIDs(cfg *config.Wrapper) error {
 	}
 	return nil
 }
+
+// A "better" version of leveldb's errors.IsCorrupted.
+func leveldbIsCorrupted(err error) bool {
+	switch {
+	case err == nil:
+		return false
+
+	case errors.IsCorrupted(err):
+		return true
+
+	case strings.Contains(err.Error(), "corrupted"):
+		return true
+	}
+
+	return false
+}