Commit e3bcfa17 authored by Audrius Butkevicius's avatar Audrius Butkevicius

Use leveldb database lock for concurrent upgrade protection (fixes #703)

Doesn't work if config directories are different though
parent 928198bb
...@@ -223,6 +223,15 @@ func main() { ...@@ -223,6 +223,15 @@ func main() {
return 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 { if doUpgrade || doUpgradeCheck {
rel, err := upgrade.LatestRelease(strings.Contains(Version, "-beta")) rel, err := upgrade.LatestRelease(strings.Contains(Version, "-beta"))
if err != nil { if err != nil {
...@@ -237,6 +246,12 @@ func main() { ...@@ -237,6 +246,12 @@ func main() {
l.Infof("Upgrade available (current %q < latest %q)", Version, rel.Tag) l.Infof("Upgrade available (current %q < latest %q)", Version, rel.Tag)
if doUpgrade { 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) err = upgrade.UpgradeTo(rel, GoArchExtra)
if err != nil { if err != nil {
l.Fatalln("Upgrade:", err) // exits 1 l.Fatalln("Upgrade:", err) // exits 1
...@@ -253,12 +268,6 @@ func main() { ...@@ -253,12 +268,6 @@ func main() {
return 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") != "" { if os.Getenv("STNORESTART") != "" {
syncthingMain() syncthingMain()
} else { } else {
...@@ -300,9 +309,7 @@ func syncthingMain() { ...@@ -300,9 +309,7 @@ func syncthingMain() {
} }
} }
// Ensure that our home directory exists and that we have a certificate and key. // Ensure that that we have a certificate and key.
ensureDir(confDir, 0700)
cert, err = loadCert(confDir, "") cert, err = loadCert(confDir, "")
if err != nil { if err != nil {
newCertificate(confDir, "") newCertificate(confDir, "")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment