From e3bcfa17f80744e18e76d9f6d34dcde3d4b2bc5d Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Wed, 17 Sep 2014 23:19:23 +0100 Subject: [PATCH] Use leveldb database lock for concurrent upgrade protection (fixes #703) Doesn't work if config directories are different though --- cmd/syncthing/main.go | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/cmd/syncthing/main.go b/cmd/syncthing/main.go index 181ac507f..3911c8fda 100644 --- a/cmd/syncthing/main.go +++ b/cmd/syncthing/main.go @@ -223,6 +223,15 @@ func main() { return } + confDir = expandTilde(confDir) + + if info, err := os.Stat(confDir); err == nil && !info.IsDir() { + l.Fatalln("Config directory", confDir, "is not a directory") + } + + // Ensure that our home directory exists. + ensureDir(confDir, 0700) + if doUpgrade || doUpgradeCheck { rel, err := upgrade.LatestRelease(strings.Contains(Version, "-beta")) if err != nil { @@ -237,6 +246,12 @@ func main() { l.Infof("Upgrade available (current %q < latest %q)", Version, rel.Tag) if doUpgrade { + // Use leveldb database locks to protect against concurrent upgrades + _, err = leveldb.OpenFile(filepath.Join(confDir, "index"), &opt.Options{CachedOpenFiles: 100}) + if err != nil { + l.Fatalln("Cannot upgrade, database seems to be locked. Is another copy of Syncthing already running?") + } + err = upgrade.UpgradeTo(rel, GoArchExtra) if err != nil { l.Fatalln("Upgrade:", err) // exits 1 @@ -253,12 +268,6 @@ func main() { return } - confDir = expandTilde(confDir) - - if info, err := os.Stat(confDir); err == nil && !info.IsDir() { - l.Fatalln("Config directory", confDir, "is not a directory") - } - if os.Getenv("STNORESTART") != "" { syncthingMain() } else { @@ -300,9 +309,7 @@ func syncthingMain() { } } - // Ensure that our home directory exists and that we have a certificate and key. - - ensureDir(confDir, 0700) + // Ensure that that we have a certificate and key. cert, err = loadCert(confDir, "") if err != nil { newCertificate(confDir, "")