mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
e23347e5b5
This avoids needing to rename it everywhere it's imported. PiperOrigin-RevId: 693930089
171 lines
4.5 KiB
Go
171 lines
4.5 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/cpuid"
|
|
"gvisor.dev/gvisor/pkg/devutil"
|
|
"gvisor.dev/gvisor/pkg/sentry/inet"
|
|
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
|
"gvisor.dev/gvisor/pkg/sentry/kernel/ipc"
|
|
"gvisor.dev/gvisor/pkg/sentry/kernel/shm"
|
|
"gvisor.dev/gvisor/pkg/sentry/ktime"
|
|
"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 (*Task) Deadline() (time.Time, bool) {
|
|
return time.Time{}, false
|
|
}
|
|
|
|
// Done implements context.Context.Done.
|
|
func (*Task) Done() <-chan struct{} {
|
|
return nil
|
|
}
|
|
|
|
// Err implements context.Context.Err.
|
|
func (*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 any) any {
|
|
// 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 any, isTaskGoroutine bool) any {
|
|
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()
|
|
}
|
|
utsns := t.utsns
|
|
utsns.IncRef()
|
|
return utsns
|
|
case ipc.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 auth.CtxThreadGroupID:
|
|
return int32(t.tg.ID())
|
|
case vfs.CtxRoot:
|
|
if !isTaskGoroutine {
|
|
t.mu.Lock()
|
|
defer t.mu.Unlock()
|
|
}
|
|
return t.fsContext.RootDirectory()
|
|
case vfs.CtxMountNamespace:
|
|
if !isTaskGoroutine {
|
|
t.mu.Lock()
|
|
defer t.mu.Unlock()
|
|
}
|
|
t.mountNamespace.IncRef()
|
|
return t.mountNamespace
|
|
case devutil.CtxDevGoferClient:
|
|
return t.k.GetDevGoferClient(t.k.ContainerName(t.containerID))
|
|
case inet.CtxStack:
|
|
return t.NetworkContext()
|
|
case inet.CtxNamespaceByFD:
|
|
return t.NetworkNamespaceByFD
|
|
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.CtxMemoryCgroupID:
|
|
return t.memCgID.Load()
|
|
case pgalloc.CtxMemoryFile:
|
|
return t.k.mf
|
|
case platform.CtxPlatform:
|
|
return t.k
|
|
case shm.CtxDeviceID:
|
|
return t.k.sysVShmDevID
|
|
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
|
|
case cpuid.CtxFeatureSet:
|
|
return t.k.featureSet
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// fallbackContext adds a level of indirection for embedding to resolve
|
|
// ambiguity for method resolution. We favor context.NoTask.
|
|
type fallbackTask struct {
|
|
*Task
|
|
}
|
|
|
|
// 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.NoTask
|
|
fallbackTask
|
|
}
|
|
|
|
// Value implements context.Context.Value.
|
|
func (t *taskAsyncContext) Value(key any) any {
|
|
return t.fallbackTask.contextValue(key, false /* isTaskGoroutine */)
|
|
}
|
|
|
|
// 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{
|
|
fallbackTask: fallbackTask{t},
|
|
}
|
|
}
|