mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
2bed0bb096
Fixes #5974 Updates #161 PiperOrigin-RevId: 375024740
195 lines
5.1 KiB
Go
195 lines
5.1 KiB
Go
// Copyright 2020 The gVisor Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package kernel
|
|
|
|
import (
|
|
"time"
|
|
|
|
"gvisor.dev/gvisor/pkg/abi/linux"
|
|
"gvisor.dev/gvisor/pkg/context"
|
|
"gvisor.dev/gvisor/pkg/log"
|
|
"gvisor.dev/gvisor/pkg/sentry/fs"
|
|
"gvisor.dev/gvisor/pkg/sentry/inet"
|
|
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
|
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
|
"gvisor.dev/gvisor/pkg/sentry/limits"
|
|
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
|
|
"gvisor.dev/gvisor/pkg/sentry/platform"
|
|
"gvisor.dev/gvisor/pkg/sentry/unimpl"
|
|
"gvisor.dev/gvisor/pkg/sentry/uniqueid"
|
|
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
|
"gvisor.dev/gvisor/pkg/sync"
|
|
)
|
|
|
|
// Deadline implements context.Context.Deadline.
|
|
func (t *Task) Deadline() (time.Time, bool) {
|
|
return time.Time{}, false
|
|
}
|
|
|
|
// Done implements context.Context.Done.
|
|
func (t *Task) Done() <-chan struct{} {
|
|
return nil
|
|
}
|
|
|
|
// Err implements context.Context.Err.
|
|
func (t *Task) Err() error {
|
|
return nil
|
|
}
|
|
|
|
// Value implements context.Context.Value.
|
|
//
|
|
// Preconditions: The caller must be running on the task goroutine.
|
|
func (t *Task) Value(key interface{}) interface{} {
|
|
// This function is very hot; skip this check outside of +race builds.
|
|
if sync.RaceEnabled {
|
|
t.assertTaskGoroutine()
|
|
}
|
|
return t.contextValue(key, true /* isTaskGoroutine */)
|
|
}
|
|
|
|
func (t *Task) contextValue(key interface{}, isTaskGoroutine bool) interface{} {
|
|
switch key {
|
|
case CtxCanTrace:
|
|
return t.CanTrace
|
|
case CtxKernel:
|
|
return t.k
|
|
case CtxPIDNamespace:
|
|
return t.tg.pidns
|
|
case CtxUTSNamespace:
|
|
if !isTaskGoroutine {
|
|
t.mu.Lock()
|
|
defer t.mu.Unlock()
|
|
}
|
|
return t.utsns
|
|
case CtxIPCNamespace:
|
|
if !isTaskGoroutine {
|
|
t.mu.Lock()
|
|
defer t.mu.Unlock()
|
|
}
|
|
ipcns := t.ipcns
|
|
ipcns.IncRef()
|
|
return ipcns
|
|
case CtxTask:
|
|
return t
|
|
case auth.CtxCredentials:
|
|
return t.creds.Load()
|
|
case context.CtxThreadGroupID:
|
|
return int32(t.tg.ID())
|
|
case fs.CtxRoot:
|
|
if !isTaskGoroutine {
|
|
t.mu.Lock()
|
|
defer t.mu.Unlock()
|
|
}
|
|
return t.fsContext.RootDirectory()
|
|
case vfs.CtxRoot:
|
|
if !isTaskGoroutine {
|
|
t.mu.Lock()
|
|
defer t.mu.Unlock()
|
|
}
|
|
return t.fsContext.RootDirectoryVFS2()
|
|
case vfs.CtxMountNamespace:
|
|
if !isTaskGoroutine {
|
|
t.mu.Lock()
|
|
defer t.mu.Unlock()
|
|
}
|
|
t.mountNamespaceVFS2.IncRef()
|
|
return t.mountNamespaceVFS2
|
|
case fs.CtxDirentCacheLimiter:
|
|
return t.k.DirentCacheLimiter
|
|
case inet.CtxStack:
|
|
return t.NetworkContext()
|
|
case ktime.CtxRealtimeClock:
|
|
return t.k.RealtimeClock()
|
|
case limits.CtxLimits:
|
|
return t.tg.limits
|
|
case linux.CtxSignalNoInfoFunc:
|
|
return func(sig linux.Signal) error {
|
|
return t.SendSignal(SignalInfoNoInfo(sig, t, t))
|
|
}
|
|
case pgalloc.CtxMemoryFile:
|
|
return t.k.mf
|
|
case pgalloc.CtxMemoryFileProvider:
|
|
return t.k
|
|
case platform.CtxPlatform:
|
|
return t.k
|
|
case uniqueid.CtxGlobalUniqueID:
|
|
return t.k.UniqueID()
|
|
case uniqueid.CtxGlobalUniqueIDProvider:
|
|
return t.k
|
|
case uniqueid.CtxInotifyCookie:
|
|
return t.k.GenerateInotifyCookie()
|
|
case unimpl.CtxEvents:
|
|
return t.k
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// taskAsyncContext implements context.Context for a goroutine that performs
|
|
// work on behalf of a Task, but is not the task goroutine.
|
|
type taskAsyncContext struct {
|
|
context.NoopSleeper
|
|
|
|
t *Task
|
|
}
|
|
|
|
// AsyncContext returns a context.Context representing t. The returned
|
|
// context.Context is intended for use by goroutines other than t's task
|
|
// goroutine; for example, signal delivery to t will not interrupt goroutines
|
|
// that are blocking using the returned context.Context.
|
|
func (t *Task) AsyncContext() context.Context {
|
|
return taskAsyncContext{t: t}
|
|
}
|
|
|
|
// Debugf implements log.Logger.Debugf.
|
|
func (ctx taskAsyncContext) Debugf(format string, v ...interface{}) {
|
|
ctx.t.Debugf(format, v...)
|
|
}
|
|
|
|
// Infof implements log.Logger.Infof.
|
|
func (ctx taskAsyncContext) Infof(format string, v ...interface{}) {
|
|
ctx.t.Infof(format, v...)
|
|
}
|
|
|
|
// Warningf implements log.Logger.Warningf.
|
|
func (ctx taskAsyncContext) Warningf(format string, v ...interface{}) {
|
|
ctx.t.Warningf(format, v...)
|
|
}
|
|
|
|
// IsLogging implements log.Logger.IsLogging.
|
|
func (ctx taskAsyncContext) IsLogging(level log.Level) bool {
|
|
return ctx.t.IsLogging(level)
|
|
}
|
|
|
|
// Deadline implements context.Context.Deadline.
|
|
func (ctx taskAsyncContext) Deadline() (time.Time, bool) {
|
|
return time.Time{}, false
|
|
}
|
|
|
|
// Done implements context.Context.Done.
|
|
func (ctx taskAsyncContext) Done() <-chan struct{} {
|
|
return nil
|
|
}
|
|
|
|
// Err implements context.Context.Err.
|
|
func (ctx taskAsyncContext) Err() error {
|
|
return nil
|
|
}
|
|
|
|
// Value implements context.Context.Value.
|
|
func (ctx taskAsyncContext) Value(key interface{}) interface{} {
|
|
return ctx.t.contextValue(key, false /* isTaskGoroutine */)
|
|
}
|