Răsfoiți Sursa

Update vendored bolt

- Backport panic/crash fixes from bbolt
Rod Hynes 6 ani în urmă
părinte
comite
b01998f4e1

+ 33 - 3
vendor/github.com/Psiphon-Labs/bolt/db.go

@@ -110,6 +110,10 @@ type DB struct {
 	freelist *freelist
 	stats    Stats
 
+	// [Psiphon]
+	// https://github.com/etcd-io/bbolt/commit/b3e98dcb3752e0a8d5db6503b80fe19e462fdb73
+	mmapErr error // set on mmap failure; subsequently returned by all methods
+
 	pagePool sync.Pool
 
 	batchMu sync.Mutex
@@ -275,7 +279,13 @@ func (db *DB) mmap(minsz int) error {
 
 	// Memory-map the data file as a byte slice.
 	if err := mmap(db, size); err != nil {
-		return err
+
+		// [Psiphon]
+		// https://github.com/etcd-io/bbolt/commit/b3e98dcb3752e0a8d5db6503b80fe19e462fdb73
+		// If mmap fails, we cannot safely continue. Mark the db as unusable,
+		// causing all future calls to return the mmap error.
+		db.mmapErr = MmapError(err.Error())
+		return db.mmapErr
 	}
 
 	// Save references to the meta pages.
@@ -395,8 +405,11 @@ func (db *DB) Close() error {
 	db.metalock.Lock()
 	defer db.metalock.Unlock()
 
-	db.mmaplock.RLock()
-	defer db.mmaplock.RUnlock()
+	// [Psiphon]
+	// https://github.com/etcd-io/bbolt/commit/e06ec0a754bc30c2e17ad871962e71635bf94d45
+	// "Fix Close() to wait for view transactions by getting a full lock on mmaplock"
+	db.mmaplock.Lock()
+	defer db.mmaplock.Unlock()
 
 	return db.close()
 }
@@ -481,6 +494,15 @@ func (db *DB) beginTx() (*Tx, error) {
 		return nil, ErrDatabaseNotOpen
 	}
 
+	// [Psiphon]
+	// https://github.com/etcd-io/bbolt/commit/b3e98dcb3752e0a8d5db6503b80fe19e462fdb73
+	// Return mmap error if a previous mmap failed.
+	if db.mmapErr != nil {
+		db.mmaplock.RUnlock()
+		db.metalock.Unlock()
+		return nil, db.mmapErr
+	}
+
 	// Create a transaction associated with the database.
 	t := &Tx{}
 	t.init(db)
@@ -522,6 +544,14 @@ func (db *DB) beginRWTx() (*Tx, error) {
 		return nil, ErrDatabaseNotOpen
 	}
 
+	// [Psiphon]
+	// https://github.com/etcd-io/bbolt/commit/b3e98dcb3752e0a8d5db6503b80fe19e462fdb73
+	// Return mmap error if a previous mmap failed.
+	if db.mmapErr != nil {
+		db.rwlock.Unlock()
+		return nil, db.mmapErr
+	}
+
 	// Create a transaction associated with the database.
 	t := &Tx{writable: true}
 	t.init(db)

+ 10 - 0
vendor/github.com/Psiphon-Labs/bolt/errors.go

@@ -69,3 +69,13 @@ var (
 	// non-bucket key on an existing bucket key.
 	ErrIncompatibleValue = errors.New("incompatible value")
 )
+
+// [Psiphon]
+// https://github.com/etcd-io/bbolt/commit/b3e98dcb3752e0a8d5db6503b80fe19e462fdb73
+
+// MmapError represents an error resulting from a failed mmap call. Typically,
+// this error means that no further database writes will be possible. The most
+// common cause is insufficient disk space.
+type MmapError string
+
+func (e MmapError) Error() string { return string(e) }

+ 9 - 0
vendor/github.com/Psiphon-Labs/bolt/tx.go

@@ -250,6 +250,15 @@ func (tx *Tx) rollback() {
 	if tx.db == nil {
 		return
 	}
+
+	// [Psiphon]
+	// https://github.com/etcd-io/bbolt/commit/b3e98dcb3752e0a8d5db6503b80fe19e462fdb73
+	// If the transaction failed due to mmap, rollback is futile.
+	if tx.db.mmapErr != nil {
+		tx.close()
+		return
+	}
+
 	if tx.writable {
 		tx.db.freelist.rollback(tx.meta.txid)
 		tx.db.freelist.reload(tx.db.page(tx.db.meta().freelist))

+ 3 - 3
vendor/vendor.json

@@ -33,10 +33,10 @@
 			"revisionTime": "2017-02-28T16:03:01Z"
 		},
 		{
-			"checksumSHA1": "3dYPdIMg6hc6whNAEXrMm09WFW0=",
+			"checksumSHA1": "ijTqnpkvC8IM47rIKnK0L4QSqmk=",
 			"path": "github.com/Psiphon-Labs/bolt",
-			"revision": "c6e046a80d4b4c6c87b9563b9dd92098f4f6f50a",
-			"revisionTime": "2017-08-14T17:37:24Z"
+			"revision": "6667eecf83b5dbd480cdb6265d95efc92c0623a6",
+			"revisionTime": "2019-07-19T02:57:58Z"
 		},
 		{
 			"checksumSHA1": "d3DwsdacdFn1/KCG/2uPV1PwR3s=",