summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/vfs
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-10-23 16:23:00 +0000
committergVisor bot <gvisor-bot@google.com>2020-10-23 16:23:00 +0000
commit034e892a8555ed3e39737dee1d3d441f2412756d (patch)
tree7917e66d96b1be8a7fa2d94367098fce737ed4f2 /pkg/sentry/vfs
parent91d7460880c16fe0025540db48721c75d9609df3 (diff)
parent9ca66ec59882ea673a6fae9ae2e36989d88dc9d1 (diff)
Merge release-20201019.0-34-g9ca66ec59 (automated)
Diffstat (limited to 'pkg/sentry/vfs')
-rw-r--r--pkg/sentry/vfs/file_description_refs.go42
-rw-r--r--pkg/sentry/vfs/filesystem_refs.go42
-rw-r--r--pkg/sentry/vfs/mount_namespace_refs.go42
-rw-r--r--pkg/sentry/vfs/vfs_state_autogen.go9
4 files changed, 57 insertions, 78 deletions
diff --git a/pkg/sentry/vfs/file_description_refs.go b/pkg/sentry/vfs/file_description_refs.go
index bdd7e6554..951cfbd4d 100644
--- a/pkg/sentry/vfs/file_description_refs.go
+++ b/pkg/sentry/vfs/file_description_refs.go
@@ -2,11 +2,9 @@ package vfs
import (
"fmt"
- "runtime"
"sync/atomic"
- "gvisor.dev/gvisor/pkg/log"
- refs_vfs1 "gvisor.dev/gvisor/pkg/refs"
+ "gvisor.dev/gvisor/pkg/refsvfs2"
)
// ownerType is used to customize logging. Note that we use a pointer to T so
@@ -19,11 +17,6 @@ var FileDescriptionownerType *FileDescription
// Note that the number of references is actually refCount + 1 so that a default
// zero-value Refs object contains one reference.
//
-// TODO(gvisor.dev/issue/1486): Store stack traces when leak check is enabled in
-// a map with 16-bit hashes, and store the hash in the top 16 bits of refCount.
-// This will allow us to add stack trace information to the leak messages
-// without growing the size of Refs.
-//
// +stateify savable
type FileDescriptionRefs struct {
// refCount is composed of two fields:
@@ -36,24 +29,16 @@ type FileDescriptionRefs struct {
refCount int64
}
-func (r *FileDescriptionRefs) finalize() {
- var note string
- switch refs_vfs1.GetLeakMode() {
- case refs_vfs1.NoLeakChecking:
- return
- case refs_vfs1.UninitializedLeakChecking:
- note = "(Leak checker uninitialized): "
- }
- if n := r.ReadRefs(); n != 0 {
- log.Warningf("%sRefs %p owned by %T garbage collected with ref count of %d (want 0)", note, r, FileDescriptionownerType, n)
+// EnableLeakCheck enables reference leak checking on r.
+func (r *FileDescriptionRefs) EnableLeakCheck() {
+ if refsvfs2.LeakCheckEnabled() {
+ refsvfs2.Register(r, fmt.Sprintf("%T", FileDescriptionownerType))
}
}
-// EnableLeakCheck checks for reference leaks when Refs gets garbage collected.
-func (r *FileDescriptionRefs) EnableLeakCheck() {
- if refs_vfs1.GetLeakMode() != refs_vfs1.NoLeakChecking {
- runtime.SetFinalizer(r, (*FileDescriptionRefs).finalize)
- }
+// LeakMessage implements refsvfs2.CheckedObject.LeakMessage.
+func (r *FileDescriptionRefs) LeakMessage() string {
+ return fmt.Sprintf("%T %p: reference count of %d instead of 0", FileDescriptionownerType, r, r.ReadRefs())
}
// ReadRefs returns the current number of references. The returned count is
@@ -68,7 +53,7 @@ func (r *FileDescriptionRefs) ReadRefs() int64 {
//go:nosplit
func (r *FileDescriptionRefs) IncRef() {
if v := atomic.AddInt64(&r.refCount, 1); v <= 0 {
- panic(fmt.Sprintf("Incrementing non-positive ref count %p owned by %T", r, FileDescriptionownerType))
+ panic(fmt.Sprintf("Incrementing non-positive count %p on %T", r, FileDescriptionownerType))
}
}
@@ -110,9 +95,18 @@ func (r *FileDescriptionRefs) DecRef(destroy func()) {
panic(fmt.Sprintf("Decrementing non-positive ref count %p, owned by %T", r, FileDescriptionownerType))
case v == -1:
+ if refsvfs2.LeakCheckEnabled() {
+ refsvfs2.Unregister(r, fmt.Sprintf("%T", FileDescriptionownerType))
+ }
if destroy != nil {
destroy()
}
}
}
+
+func (r *FileDescriptionRefs) afterLoad() {
+ if refsvfs2.LeakCheckEnabled() && r.ReadRefs() > 0 {
+ r.EnableLeakCheck()
+ }
+}
diff --git a/pkg/sentry/vfs/filesystem_refs.go b/pkg/sentry/vfs/filesystem_refs.go
index 38a9a986f..f1abc120d 100644
--- a/pkg/sentry/vfs/filesystem_refs.go
+++ b/pkg/sentry/vfs/filesystem_refs.go
@@ -2,11 +2,9 @@ package vfs
import (
"fmt"
- "runtime"
"sync/atomic"
- "gvisor.dev/gvisor/pkg/log"
- refs_vfs1 "gvisor.dev/gvisor/pkg/refs"
+ "gvisor.dev/gvisor/pkg/refsvfs2"
)
// ownerType is used to customize logging. Note that we use a pointer to T so
@@ -19,11 +17,6 @@ var FilesystemownerType *Filesystem
// Note that the number of references is actually refCount + 1 so that a default
// zero-value Refs object contains one reference.
//
-// TODO(gvisor.dev/issue/1486): Store stack traces when leak check is enabled in
-// a map with 16-bit hashes, and store the hash in the top 16 bits of refCount.
-// This will allow us to add stack trace information to the leak messages
-// without growing the size of Refs.
-//
// +stateify savable
type FilesystemRefs struct {
// refCount is composed of two fields:
@@ -36,24 +29,16 @@ type FilesystemRefs struct {
refCount int64
}
-func (r *FilesystemRefs) finalize() {
- var note string
- switch refs_vfs1.GetLeakMode() {
- case refs_vfs1.NoLeakChecking:
- return
- case refs_vfs1.UninitializedLeakChecking:
- note = "(Leak checker uninitialized): "
- }
- if n := r.ReadRefs(); n != 0 {
- log.Warningf("%sRefs %p owned by %T garbage collected with ref count of %d (want 0)", note, r, FilesystemownerType, n)
+// EnableLeakCheck enables reference leak checking on r.
+func (r *FilesystemRefs) EnableLeakCheck() {
+ if refsvfs2.LeakCheckEnabled() {
+ refsvfs2.Register(r, fmt.Sprintf("%T", FilesystemownerType))
}
}
-// EnableLeakCheck checks for reference leaks when Refs gets garbage collected.
-func (r *FilesystemRefs) EnableLeakCheck() {
- if refs_vfs1.GetLeakMode() != refs_vfs1.NoLeakChecking {
- runtime.SetFinalizer(r, (*FilesystemRefs).finalize)
- }
+// LeakMessage implements refsvfs2.CheckedObject.LeakMessage.
+func (r *FilesystemRefs) LeakMessage() string {
+ return fmt.Sprintf("%T %p: reference count of %d instead of 0", FilesystemownerType, r, r.ReadRefs())
}
// ReadRefs returns the current number of references. The returned count is
@@ -68,7 +53,7 @@ func (r *FilesystemRefs) ReadRefs() int64 {
//go:nosplit
func (r *FilesystemRefs) IncRef() {
if v := atomic.AddInt64(&r.refCount, 1); v <= 0 {
- panic(fmt.Sprintf("Incrementing non-positive ref count %p owned by %T", r, FilesystemownerType))
+ panic(fmt.Sprintf("Incrementing non-positive count %p on %T", r, FilesystemownerType))
}
}
@@ -110,9 +95,18 @@ func (r *FilesystemRefs) DecRef(destroy func()) {
panic(fmt.Sprintf("Decrementing non-positive ref count %p, owned by %T", r, FilesystemownerType))
case v == -1:
+ if refsvfs2.LeakCheckEnabled() {
+ refsvfs2.Unregister(r, fmt.Sprintf("%T", FilesystemownerType))
+ }
if destroy != nil {
destroy()
}
}
}
+
+func (r *FilesystemRefs) afterLoad() {
+ if refsvfs2.LeakCheckEnabled() && r.ReadRefs() > 0 {
+ r.EnableLeakCheck()
+ }
+}
diff --git a/pkg/sentry/vfs/mount_namespace_refs.go b/pkg/sentry/vfs/mount_namespace_refs.go
index 63285fb8e..32e28ebf8 100644
--- a/pkg/sentry/vfs/mount_namespace_refs.go
+++ b/pkg/sentry/vfs/mount_namespace_refs.go
@@ -2,11 +2,9 @@ package vfs
import (
"fmt"
- "runtime"
"sync/atomic"
- "gvisor.dev/gvisor/pkg/log"
- refs_vfs1 "gvisor.dev/gvisor/pkg/refs"
+ "gvisor.dev/gvisor/pkg/refsvfs2"
)
// ownerType is used to customize logging. Note that we use a pointer to T so
@@ -19,11 +17,6 @@ var MountNamespaceownerType *MountNamespace
// Note that the number of references is actually refCount + 1 so that a default
// zero-value Refs object contains one reference.
//
-// TODO(gvisor.dev/issue/1486): Store stack traces when leak check is enabled in
-// a map with 16-bit hashes, and store the hash in the top 16 bits of refCount.
-// This will allow us to add stack trace information to the leak messages
-// without growing the size of Refs.
-//
// +stateify savable
type MountNamespaceRefs struct {
// refCount is composed of two fields:
@@ -36,24 +29,16 @@ type MountNamespaceRefs struct {
refCount int64
}
-func (r *MountNamespaceRefs) finalize() {
- var note string
- switch refs_vfs1.GetLeakMode() {
- case refs_vfs1.NoLeakChecking:
- return
- case refs_vfs1.UninitializedLeakChecking:
- note = "(Leak checker uninitialized): "
- }
- if n := r.ReadRefs(); n != 0 {
- log.Warningf("%sRefs %p owned by %T garbage collected with ref count of %d (want 0)", note, r, MountNamespaceownerType, n)
+// EnableLeakCheck enables reference leak checking on r.
+func (r *MountNamespaceRefs) EnableLeakCheck() {
+ if refsvfs2.LeakCheckEnabled() {
+ refsvfs2.Register(r, fmt.Sprintf("%T", MountNamespaceownerType))
}
}
-// EnableLeakCheck checks for reference leaks when Refs gets garbage collected.
-func (r *MountNamespaceRefs) EnableLeakCheck() {
- if refs_vfs1.GetLeakMode() != refs_vfs1.NoLeakChecking {
- runtime.SetFinalizer(r, (*MountNamespaceRefs).finalize)
- }
+// LeakMessage implements refsvfs2.CheckedObject.LeakMessage.
+func (r *MountNamespaceRefs) LeakMessage() string {
+ return fmt.Sprintf("%T %p: reference count of %d instead of 0", MountNamespaceownerType, r, r.ReadRefs())
}
// ReadRefs returns the current number of references. The returned count is
@@ -68,7 +53,7 @@ func (r *MountNamespaceRefs) ReadRefs() int64 {
//go:nosplit
func (r *MountNamespaceRefs) IncRef() {
if v := atomic.AddInt64(&r.refCount, 1); v <= 0 {
- panic(fmt.Sprintf("Incrementing non-positive ref count %p owned by %T", r, MountNamespaceownerType))
+ panic(fmt.Sprintf("Incrementing non-positive count %p on %T", r, MountNamespaceownerType))
}
}
@@ -110,9 +95,18 @@ func (r *MountNamespaceRefs) DecRef(destroy func()) {
panic(fmt.Sprintf("Decrementing non-positive ref count %p, owned by %T", r, MountNamespaceownerType))
case v == -1:
+ if refsvfs2.LeakCheckEnabled() {
+ refsvfs2.Unregister(r, fmt.Sprintf("%T", MountNamespaceownerType))
+ }
if destroy != nil {
destroy()
}
}
}
+
+func (r *MountNamespaceRefs) afterLoad() {
+ if refsvfs2.LeakCheckEnabled() && r.ReadRefs() > 0 {
+ r.EnableLeakCheck()
+ }
+}
diff --git a/pkg/sentry/vfs/vfs_state_autogen.go b/pkg/sentry/vfs/vfs_state_autogen.go
index d78221080..03c84829d 100644
--- a/pkg/sentry/vfs/vfs_state_autogen.go
+++ b/pkg/sentry/vfs/vfs_state_autogen.go
@@ -690,10 +690,9 @@ func (r *FileDescriptionRefs) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(0, &r.refCount)
}
-func (r *FileDescriptionRefs) afterLoad() {}
-
func (r *FileDescriptionRefs) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &r.refCount)
+ stateSourceObject.AfterLoad(r.afterLoad)
}
func (fs *Filesystem) StateTypeName() string {
@@ -802,10 +801,9 @@ func (r *FilesystemRefs) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(0, &r.refCount)
}
-func (r *FilesystemRefs) afterLoad() {}
-
func (r *FilesystemRefs) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &r.refCount)
+ stateSourceObject.AfterLoad(r.afterLoad)
}
func (r *registeredFilesystemType) StateTypeName() string {
@@ -1169,10 +1167,9 @@ func (r *MountNamespaceRefs) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(0, &r.refCount)
}
-func (r *MountNamespaceRefs) afterLoad() {}
-
func (r *MountNamespaceRefs) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &r.refCount)
+ stateSourceObject.AfterLoad(r.afterLoad)
}
func (g *GetDentryOptions) StateTypeName() string {