...

Source file src/github.com/Microsoft/hcsshim/internal/guest/runtime/hcsv2/uvm_state.go

Documentation: github.com/Microsoft/hcsshim/internal/guest/runtime/hcsv2

     1  //go:build linux
     2  // +build linux
     3  
     4  package hcsv2
     5  
     6  import (
     7  	"fmt"
     8  	"path/filepath"
     9  	"strings"
    10  	"sync"
    11  )
    12  
    13  type rwDevice struct {
    14  	mountPath  string
    15  	sourcePath string
    16  	encrypted  bool
    17  }
    18  
    19  type hostMounts struct {
    20  	stateMutex sync.Mutex
    21  
    22  	// Holds information about read-write devices, which can be encrypted and
    23  	// contain overlay fs upper/work directory mounts.
    24  	readWriteMounts map[string]*rwDevice
    25  }
    26  
    27  func newHostMounts() *hostMounts {
    28  	return &hostMounts{
    29  		readWriteMounts: map[string]*rwDevice{},
    30  	}
    31  }
    32  
    33  // AddRWDevice adds read-write device metadata for device mounted at `mountPath`.
    34  // Returns an error if there's an existing device mounted at `mountPath` location.
    35  func (hm *hostMounts) AddRWDevice(mountPath string, sourcePath string, encrypted bool) error {
    36  	hm.stateMutex.Lock()
    37  	defer hm.stateMutex.Unlock()
    38  
    39  	mountTarget := filepath.Clean(mountPath)
    40  	if source, ok := hm.readWriteMounts[mountTarget]; ok {
    41  		return fmt.Errorf("read-write with source %q and mount target %q already exists", source.sourcePath, mountPath)
    42  	}
    43  	hm.readWriteMounts[mountTarget] = &rwDevice{
    44  		mountPath:  mountTarget,
    45  		sourcePath: sourcePath,
    46  		encrypted:  encrypted,
    47  	}
    48  	return nil
    49  }
    50  
    51  // RemoveRWDevice removes the read-write device metadata for device mounted at
    52  // `mountPath`.
    53  func (hm *hostMounts) RemoveRWDevice(mountPath string, sourcePath string) error {
    54  	hm.stateMutex.Lock()
    55  	defer hm.stateMutex.Unlock()
    56  
    57  	unmountTarget := filepath.Clean(mountPath)
    58  	device, ok := hm.readWriteMounts[unmountTarget]
    59  	if !ok {
    60  		// already removed or didn't exist
    61  		return nil
    62  	}
    63  	if device.sourcePath != sourcePath {
    64  		return fmt.Errorf("wrong sourcePath %s", sourcePath)
    65  	}
    66  
    67  	delete(hm.readWriteMounts, unmountTarget)
    68  	return nil
    69  }
    70  
    71  // IsEncrypted checks if the given path is a sub-path of an encrypted read-write
    72  // device.
    73  func (hm *hostMounts) IsEncrypted(path string) bool {
    74  	hm.stateMutex.Lock()
    75  	defer hm.stateMutex.Unlock()
    76  
    77  	parentPath := ""
    78  	encrypted := false
    79  	cleanPath := filepath.Clean(path)
    80  	for rwPath, rwDev := range hm.readWriteMounts {
    81  		relPath, err := filepath.Rel(rwPath, cleanPath)
    82  		// skip further checks if an error is returned or the relative path
    83  		// contains "..", meaning that the `path` isn't directly nested under
    84  		// `rwPath`.
    85  		if err != nil || strings.HasPrefix(relPath, "..") {
    86  			continue
    87  		}
    88  		if len(rwDev.mountPath) > len(parentPath) {
    89  			parentPath = rwDev.mountPath
    90  			encrypted = rwDev.encrypted
    91  		}
    92  	}
    93  	return encrypted
    94  }
    95  

View as plain text