github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/fs/sys/devices.go (about) 1 // Copyright 2018 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 sys 16 17 import ( 18 "fmt" 19 20 "github.com/SagerNet/gvisor/pkg/abi/linux" 21 "github.com/SagerNet/gvisor/pkg/context" 22 "github.com/SagerNet/gvisor/pkg/sentry/fs" 23 "github.com/SagerNet/gvisor/pkg/sentry/fs/fsutil" 24 "github.com/SagerNet/gvisor/pkg/sentry/kernel" 25 ) 26 27 // +stateify savable 28 type cpunum struct { 29 fsutil.InodeGenericChecker `state:"nosave"` 30 fsutil.InodeNoExtendedAttributes `state:"nosave"` 31 fsutil.InodeNoopRelease `state:"nosave"` 32 fsutil.InodeNoopWriteOut `state:"nosave"` 33 fsutil.InodeNotAllocatable `state:"nosave"` 34 fsutil.InodeNotDirectory `state:"nosave"` 35 fsutil.InodeNotMappable `state:"nosave"` 36 fsutil.InodeNotSocket `state:"nosave"` 37 fsutil.InodeNotSymlink `state:"nosave"` 38 fsutil.InodeNotTruncatable `state:"nosave"` 39 fsutil.InodeNotVirtual `state:"nosave"` 40 41 fsutil.InodeSimpleAttributes 42 fsutil.InodeStaticFileGetter 43 } 44 45 var _ fs.InodeOperations = (*cpunum)(nil) 46 47 func newPossible(ctx context.Context, msrc *fs.MountSource) *fs.Inode { 48 var maxCore uint 49 k := kernel.KernelFromContext(ctx) 50 if k != nil { 51 maxCore = k.ApplicationCores() - 1 52 } 53 contents := []byte(fmt.Sprintf("0-%d\n", maxCore)) 54 55 c := &cpunum{ 56 InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, fs.RootOwner, fs.FilePermsFromMode(0444), linux.SYSFS_MAGIC), 57 InodeStaticFileGetter: fsutil.InodeStaticFileGetter{ 58 Contents: contents, 59 }, 60 } 61 return newFile(ctx, c, msrc) 62 } 63 64 func newCPU(ctx context.Context, msrc *fs.MountSource) *fs.Inode { 65 m := map[string]*fs.Inode{ 66 "online": newPossible(ctx, msrc), 67 "possible": newPossible(ctx, msrc), 68 "present": newPossible(ctx, msrc), 69 } 70 71 // Add directories for each of the cpus. 72 if k := kernel.KernelFromContext(ctx); k != nil { 73 for i := 0; uint(i) < k.ApplicationCores(); i++ { 74 m[fmt.Sprintf("cpu%d", i)] = newDir(ctx, msrc, nil) 75 } 76 } 77 78 return newDir(ctx, msrc, m) 79 } 80 81 func newSystemDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { 82 return newDir(ctx, msrc, map[string]*fs.Inode{ 83 "cpu": newCPU(ctx, msrc), 84 }) 85 } 86 87 func newDevicesDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { 88 return newDir(ctx, msrc, map[string]*fs.Inode{ 89 "system": newSystemDir(ctx, msrc), 90 }) 91 }