From 5243400c3153de7508db9e1c423a14144c03567e Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Wed, 31 Jan 2018 14:43:08 +0100 Subject: [PATCH] refactor: extract fs lock into go-fs-lock License: MIT Signed-off-by: dignifiedquire --- core/commands/repo.go | 3 +- package.json | 7 +++- repo/fsrepo/fsrepo.go | 10 ++++-- repo/fsrepo/lock/lock.go | 70 ---------------------------------------- 4 files changed, 14 insertions(+), 76 deletions(-) delete mode 100644 repo/fsrepo/lock/lock.go diff --git a/core/commands/repo.go b/core/commands/repo.go index 9a80975d866..d3b90673aaa 100644 --- a/core/commands/repo.go +++ b/core/commands/repo.go @@ -15,7 +15,6 @@ import ( corerepo "github.com/ipfs/go-ipfs/core/corerepo" config "github.com/ipfs/go-ipfs/repo/config" fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" - lockfile "github.com/ipfs/go-ipfs/repo/fsrepo/lock" bstore "gx/ipfs/QmTVDM4LCSUMFNQzbDLL9zQwp8usE6QHymFdh3h8vL9v6b/go-ipfs-blockstore" cmds "gx/ipfs/QmZ9hww8R3FKrDRCYPxhN13m6XgjPDpaSvdUfisPvERzXz/go-ipfs-cmds" @@ -233,7 +232,7 @@ daemons are running. } dsLockFile := filepath.Join(dsPath, "LOCK") // TODO: get this lockfile programmatically - repoLockFile := filepath.Join(configRoot, lockfile.LockFile) + repoLockFile := filepath.Join(configRoot, fsrepo.LockFile) apiFile := filepath.Join(configRoot, "api") // TODO: get this programmatically log.Infof("Removing repo lockfile: %s", repoLockFile) diff --git a/package.json b/package.json index 01ed8b0a5b8..d047c50a441 100644 --- a/package.json +++ b/package.json @@ -575,6 +575,12 @@ "hash": "QmdbxjQWogRCHRaxhhGnYdT1oQJzL9GdqSKzCdqWr85AP2", "name": "pubsub", "version": "1.0.0" + }, + { + "author": "dignifiedquire", + "hash": "QmTAQSKWDGV7MpNGZrcj9gzbBLk3vG77EcBkCQtPphCknP", + "name": "go-fs-lock", + "version": "0.1.0" } ], "gxVersion": "0.10.0", @@ -583,4 +589,3 @@ "name": "go-ipfs", "version": "0.4.14-dev" } - diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index ad3e1f8d9d2..c9db33eb3eb 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -16,10 +16,10 @@ import ( repo "github.com/ipfs/go-ipfs/repo" "github.com/ipfs/go-ipfs/repo/common" config "github.com/ipfs/go-ipfs/repo/config" - lockfile "github.com/ipfs/go-ipfs/repo/fsrepo/lock" mfsr "github.com/ipfs/go-ipfs/repo/fsrepo/migrations" serialize "github.com/ipfs/go-ipfs/repo/fsrepo/serialize" dir "github.com/ipfs/go-ipfs/thirdparty/dir" + lockfile "gx/ipfs/QmTAQSKWDGV7MpNGZrcj9gzbBLk3vG77EcBkCQtPphCknP/go-fs-lock" "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/mitchellh/go-homedir" @@ -29,6 +29,10 @@ import ( ma "gx/ipfs/QmWWQ2Txc2c6tqjsBpzg5Ar652cHPGNsQQp2SejkNmkUMb/go-multiaddr" ) +// LockFile is the filename of the repo lock, relative to config dir +// TODO rename repo lock and hide name +const LockFile = "repo.lock" + var log = logging.Logger("fsrepo") // version number that we are currently expecting to see @@ -126,7 +130,7 @@ func open(repoPath string) (repo.Repo, error) { return nil, err } - r.lockfile, err = lockfile.Lock(r.path) + r.lockfile, err = lockfile.Lock(r.path, LockFile) if err != nil { return nil, err } @@ -297,7 +301,7 @@ func Init(repoPath string, conf *config.Config) error { // process. If true, then the repo cannot be opened by this process. func LockedByOtherProcess(repoPath string) (bool, error) { repoPath = filepath.Clean(repoPath) - locked, err := lockfile.Locked(repoPath) + locked, err := lockfile.Locked(repoPath, LockFile) if locked { log.Debugf("(%t)<->Lock is held at %s", locked, repoPath) } diff --git a/repo/fsrepo/lock/lock.go b/repo/fsrepo/lock/lock.go deleted file mode 100644 index c526141f4db..00000000000 --- a/repo/fsrepo/lock/lock.go +++ /dev/null @@ -1,70 +0,0 @@ -package lock - -import ( - "fmt" - "io" - "os" - "path" - "strings" - "syscall" - - "gx/ipfs/QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx/go-ipfs-util" - logging "gx/ipfs/QmRb5jh8z2E8hMGN2tkvs1yHynUanqnZ3UeKwgN1i9P1F8/go-log" - lock "gx/ipfs/QmWi28zbQG6B1xfaaWx5cYoLn3kBFU6pQ6GWQNRV5P6dNe/lock" -) - -// LockFile is the filename of the repo lock, relative to config dir -// TODO rename repo lock and hide name -const LockFile = "repo.lock" - -// log is the fsrepo logger -var log = logging.Logger("lock") - -func errPerm(path string) error { - return fmt.Errorf("failed to take lock at %s: permission denied", path) -} - -func Lock(confdir string) (io.Closer, error) { - return lock.Lock(path.Join(confdir, LockFile)) -} - -func Locked(confdir string) (bool, error) { - log.Debugf("Checking lock") - if !util.FileExists(path.Join(confdir, LockFile)) { - log.Debugf("File doesn't exist: %s", path.Join(confdir, LockFile)) - return false, nil - } - if lk, err := Lock(confdir); err != nil { - // EAGAIN == someone else has the lock - if err == syscall.EAGAIN { - log.Debugf("Someone else has the lock: %s", path.Join(confdir, LockFile)) - return true, nil - } - if strings.Contains(err.Error(), "resource temporarily unavailable") { - log.Debugf("Can't lock file: %s.\n reason: %s", path.Join(confdir, LockFile), err.Error()) - return true, nil - } - - // lock fails on permissions error - if os.IsPermission(err) { - log.Debugf("Lock fails on permissions error") - return false, errPerm(confdir) - } - if isLockCreatePermFail(err) { - log.Debugf("Lock fails on permissions error") - return false, errPerm(confdir) - } - - // otherwise, we cant guarantee anything, error out - return false, err - } else { - log.Debugf("No one has a lock") - lk.Close() - return false, nil - } -} - -func isLockCreatePermFail(err error) bool { - s := err.Error() - return strings.Contains(s, "Lock Create of") && strings.Contains(s, "permission denied") -}