From 7762e39fb3ad90a13034d43039112583cd0f514b Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Thu, 27 Mar 2025 09:26:21 +0000 Subject: [PATCH] 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. --- cmd/syncthing/main.go | 22 +++++++++++++++++----- go.mod | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/cmd/syncthing/main.go b/cmd/syncthing/main.go index 55dea93d7..1faff628e 100644 --- a/cmd/syncthing/main.go +++ b/cmd/syncthing/main.go @@ -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() diff --git a/go.mod b/go.mod index 163eaf2ff..f2ce0ee4d 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/getsentry/raven-go v0.2.0 github.com/go-ldap/ldap/v3 v3.4.10 github.com/gobwas/glob v0.2.3 + github.com/gofrs/flock v0.12.1 github.com/greatroar/blobloom v0.8.0 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/jackpal/gateway v1.0.16 @@ -62,7 +63,6 @@ require ( github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/gofrs/flock v0.12.1 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/pprof v0.0.0-20241009165004-a3522334989c // indirect github.com/google/uuid v1.6.0 // indirect