github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/fs/tty/fs.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 tty
    16  
    17  import (
    18  	"github.com/SagerNet/gvisor/pkg/context"
    19  	"github.com/SagerNet/gvisor/pkg/errors/linuxerr"
    20  	"github.com/SagerNet/gvisor/pkg/sentry/device"
    21  	"github.com/SagerNet/gvisor/pkg/sentry/fs"
    22  )
    23  
    24  // ptsDevice is the pseudo-filesystem device.
    25  var ptsDevice = device.NewAnonDevice()
    26  
    27  // filesystem is a devpts filesystem.
    28  //
    29  // This devpts is always in the new "multi-instance" mode. i.e., it contains a
    30  // ptmx device tied to this mount.
    31  //
    32  // +stateify savable
    33  type filesystem struct{}
    34  
    35  func init() {
    36  	fs.RegisterFilesystem(&filesystem{})
    37  }
    38  
    39  // Name matches drivers/devpts/indoe.c:devpts_fs_type.name.
    40  func (*filesystem) Name() string {
    41  	return "devpts"
    42  }
    43  
    44  // AllowUserMount allows users to mount(2) this file system.
    45  func (*filesystem) AllowUserMount() bool {
    46  	// TODO(b/29356795): Users may mount this once the terminals are in a
    47  	// usable state.
    48  	return false
    49  }
    50  
    51  // AllowUserList allows this filesystem to be listed in /proc/filesystems.
    52  func (*filesystem) AllowUserList() bool {
    53  	return true
    54  }
    55  
    56  // Flags returns that there is nothing special about this file system.
    57  func (*filesystem) Flags() fs.FilesystemFlags {
    58  	return 0
    59  }
    60  
    61  // MountSource returns a devpts root that can be positioned in the vfs.
    62  func (f *filesystem) Mount(ctx context.Context, device string, flags fs.MountSourceFlags, data string, _ interface{}) (*fs.Inode, error) {
    63  	// device is always ignored.
    64  
    65  	// No options are supported.
    66  	if data != "" {
    67  		return nil, linuxerr.EINVAL
    68  	}
    69  
    70  	return newDir(ctx, fs.NewMountSource(ctx, &superOperations{}, f, flags)), nil
    71  }
    72  
    73  // superOperations implements fs.MountSourceOperations, preventing caching.
    74  //
    75  // +stateify savable
    76  type superOperations struct{}
    77  
    78  // Revalidate implements fs.DirentOperations.Revalidate.
    79  //
    80  // It always returns true, forcing a Lookup for all entries.
    81  //
    82  // Replica entries are dropped from dir when their master is closed, so an
    83  // existing replica Dirent in the tree is not sufficient to guarantee that it
    84  // still exists on the filesystem.
    85  func (superOperations) Revalidate(context.Context, string, *fs.Inode, *fs.Inode) bool {
    86  	return true
    87  }
    88  
    89  // Keep implements fs.DirentOperations.Keep.
    90  //
    91  // Keep returns false because Revalidate would force a lookup on cached entries
    92  // anyways.
    93  func (superOperations) Keep(*fs.Dirent) bool {
    94  	return false
    95  }
    96  
    97  // CacheReaddir implements fs.DirentOperations.CacheReaddir.
    98  //
    99  // CacheReaddir returns false because entries change on master operations.
   100  func (superOperations) CacheReaddir() bool {
   101  	return false
   102  }
   103  
   104  // ResetInodeMappings implements MountSourceOperations.ResetInodeMappings.
   105  func (superOperations) ResetInodeMappings() {}
   106  
   107  // SaveInodeMapping implements MountSourceOperations.SaveInodeMapping.
   108  func (superOperations) SaveInodeMapping(*fs.Inode, string) {}
   109  
   110  // Destroy implements MountSourceOperations.Destroy.
   111  func (superOperations) Destroy(context.Context) {}