chore(syncthing): use file lock on certificate to prevent multiple instances (#10003)

This adds the locking from the SQLite branch, in preparation, so that we
do not inadvertently permit running an instance of each.
This commit is contained in:
Jakob Borg
2025-03-27 09:26:21 +00:00
committed by GitHub
parent 4235b2c406
commit 7762e39fb3
2 changed files with 18 additions and 6 deletions
+17 -5
View File
@@ -30,6 +30,7 @@ import (
"time"
"github.com/alecthomas/kong"
"github.com/gofrs/flock"
"github.com/thejerf/suture/v4"
"github.com/willabides/kongplete"
@@ -41,7 +42,6 @@ import (
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/db/backend"
"github.com/syncthing/syncthing/lib/dialer"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs"
@@ -376,13 +376,14 @@ func (options serveOptions) Run() error {
if options.Upgrade {
release, err := checkUpgrade()
if err == nil {
// Use leveldb database locks to protect against concurrent upgrades
var ldb backend.Backend
ldb, err = syncthing.OpenDBBackend(locations.Get(locations.Database), config.TuningAuto)
lf := flock.New(locations.Get(locations.CertFile))
locked, err := lf.TryLock()
if err != nil {
l.Warnln("Upgrade:", err)
os.Exit(1)
} else if locked {
err = upgradeViaRest()
} else {
_ = ldb.Close()
err = upgrade.To(release)
}
}
@@ -544,6 +545,17 @@ func syncthingMain(options serveOptions) {
os.Exit(1)
}
// Ensure we are the only running instance
lf := flock.New(locations.Get(locations.CertFile))
locked, err := lf.TryLock()
if err != nil {
l.Warnln("Failed to acquire lock:", err)
os.Exit(1)
} else if !locked {
l.Warnln("Failed to acquire lock: is another Syncthing instance already running?")
os.Exit(1)
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()