github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/vfs/context.go (about) 1 // Copyright 2019 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package vfs 16 17 import ( 18 goContext "context" 19 20 "github.com/metacubex/gvisor/pkg/context" 21 ) 22 23 // contextID is this package's type for context.Context.Value keys. 24 type contextID int 25 26 const ( 27 // CtxMountNamespace is a Context.Value key for a MountNamespace. 28 CtxMountNamespace contextID = iota 29 30 // CtxRoot is a Context.Value key for a VFS root. 31 CtxRoot 32 33 // CtxRestoreFilesystemFDMap is a Context.Value key for a map[string]int 34 // mapping filesystem unique IDs (cf. gofer.InternalFilesystemOptions.UniqueID) 35 // to host FDs. 36 CtxRestoreFilesystemFDMap 37 ) 38 39 // MountNamespaceFromContext returns the MountNamespace used by ctx. If ctx is 40 // not associated with a MountNamespace, MountNamespaceFromContext returns nil. 41 // 42 // A reference is taken on the returned MountNamespace. 43 func MountNamespaceFromContext(ctx goContext.Context) *MountNamespace { 44 if v := ctx.Value(CtxMountNamespace); v != nil { 45 return v.(*MountNamespace) 46 } 47 return nil 48 } 49 50 // RestoreFilesystemFDMapFromContext returns the RestoreFilesystemFDMap used 51 // by ctx. If ctx is not associated with a RestoreFilesystemFDMap, returns nil. 52 func RestoreFilesystemFDMapFromContext(ctx goContext.Context) map[RestoreID]int { 53 fdmap, ok := ctx.Value(CtxRestoreFilesystemFDMap).(map[RestoreID]int) 54 if !ok { 55 return nil 56 } 57 return fdmap 58 } 59 60 type mountNamespaceContext struct { 61 context.Context 62 mntns *MountNamespace 63 } 64 65 // Value implements Context.Value. 66 func (mc mountNamespaceContext) Value(key any) any { 67 switch key { 68 case CtxMountNamespace: 69 mc.mntns.IncRef() 70 return mc.mntns 71 default: 72 return mc.Context.Value(key) 73 } 74 } 75 76 // WithMountNamespace returns a copy of ctx with the given MountNamespace. 77 func WithMountNamespace(ctx context.Context, mntns *MountNamespace) context.Context { 78 return &mountNamespaceContext{ 79 Context: ctx, 80 mntns: mntns, 81 } 82 } 83 84 // RootFromContext returns the VFS root used by ctx. It takes a reference on 85 // the returned VirtualDentry. If ctx does not have a specific VFS root, 86 // RootFromContext returns a zero-value VirtualDentry. 87 func RootFromContext(ctx goContext.Context) VirtualDentry { 88 if v := ctx.Value(CtxRoot); v != nil { 89 return v.(VirtualDentry) 90 } 91 return VirtualDentry{} 92 } 93 94 type rootContext struct { 95 context.Context 96 root VirtualDentry 97 } 98 99 // WithRoot returns a copy of ctx with the given root. 100 func WithRoot(ctx context.Context, root VirtualDentry) context.Context { 101 return &rootContext{ 102 Context: ctx, 103 root: root, 104 } 105 } 106 107 // Value implements Context.Value. 108 func (rc rootContext) Value(key any) any { 109 switch key { 110 case CtxRoot: 111 rc.root.IncRef() 112 return rc.root 113 default: 114 return rc.Context.Value(key) 115 } 116 }