aboutsummaryrefslogtreecommitdiff
path: root/db.go
diff options
context:
space:
mode:
authorBen Johnson <benbjohnson@yahoo.com>2014-04-02 14:05:24 -0600
committerBen Johnson <benbjohnson@yahoo.com>2014-04-02 14:05:24 -0600
commit1eacfa948968c483d3232e4ca8e0a32df39f81e9 (patch)
treee16c6e9db2eea87fd3f5cb53402657720ba1cf4d /db.go
parentMerge pull request #109 from benbjohnson/consolidate-file-descriptors (diff)
downloaddedo-1eacfa948968c483d3232e4ca8e0a32df39f81e9.tar.gz
dedo-1eacfa948968c483d3232e4ca8e0a32df39f81e9.tar.xz
Add advisory file locking.
This commit adds advisory locking via flock() to the database file. This ensures that two separate processes cannot both open the same data file which would cause corruption. Fixes #110.
Diffstat (limited to 'db.go')
-rw-r--r--db.go12
1 files changed, 12 insertions, 0 deletions
diff --git a/db.go b/db.go
index 5cdad81..e4a4f9c 100644
--- a/db.go
+++ b/db.go
@@ -79,6 +79,14 @@ func Open(path string, mode os.FileMode) (*DB, error) {
return nil, err
}
+ // Lock file so that other processes using Bolt cannot use the database
+ // at the same time. This would cause corruption since the two processes
+ // would write meta pages and free pages separately.
+ if err := syscall.Flock(int(db.file.Fd()), syscall.LOCK_EX); err != nil {
+ _ = db.close()
+ return nil, err
+ }
+
// Default values for test hooks
db.ops.writeAt = db.file.WriteAt
@@ -267,6 +275,10 @@ func (db *DB) close() error {
// Close file handles.
if db.file != nil {
+ // Unlock the file.
+ _ = syscall.Flock(int(db.file.Fd()), syscall.LOCK_UN)
+
+ // Close the file descriptor.
if err := db.file.Close(); err != nil {
return fmt.Errorf("db file close: %s", err)
}