fs: Hold format.json readLock ref to avoid GC. (#4532)

Looks like if we follow pattern such as

```
_ = rlk
```

Go can potentially kick in GC and close the fd when
the reference is lost, only speculation is that
the cause here is `SetFinalizer` which is set on
`os.close()` internally in `os` stdlib.

This is unexpected and unsual endeavour for Go, but
we have to make sure the reference is never lost
and always dies with the server.

Fixes #4530
This commit is contained in:
Harshavardhana
2017-06-13 08:29:07 -07:00
committed by GitHub
parent c8947af227
commit 353f2d3a6e
3 changed files with 33 additions and 35 deletions

View File

@@ -42,6 +42,9 @@ type fsObjects struct {
// temporary transactions.
fsUUID string
// This value shouldn't be touched, once initialized.
fsFormatRlk *lock.RLockedFile // Is a read lock on `format.json`.
// FS rw pool.
rwPool *fsIOPool
@@ -109,6 +112,12 @@ func newFSObjectLayer(fsPath string) (ObjectLayer, error) {
return nil, fmt.Errorf("Unable to initialize '.minio.sys' meta volume, %s", err)
}
// Initialize `format.json`, this function also returns.
rlk, err := initFormatFS(fsPath)
if err != nil {
return nil, err
}
// Initialize fs objects.
fs := &fsObjects{
fsPath: fsPath,
@@ -122,10 +131,11 @@ func newFSObjectLayer(fsPath string) (ObjectLayer, error) {
},
}
// Initialize `format.json`.
if err = initFormatFS(fsPath, fsUUID); err != nil {
return nil, err
}
// Once the filesystem has initialized hold the read lock for
// the life time of the server. This is done to ensure that under
// shared backend mode for FS, remote servers do not migrate
// or cause changes on backend format.
fs.fsFormatRlk = rlk
// Initialize and load bucket policies.
err = initBucketPolicies(fs)