...

Source file src/github.com/opencontainers/runc/libcontainer/mount_linux.go

Documentation: github.com/opencontainers/runc/libcontainer

     1  package libcontainer
     2  
     3  import (
     4  	"io/fs"
     5  	"strconv"
     6  
     7  	"golang.org/x/sys/unix"
     8  )
     9  
    10  // mountError holds an error from a failed mount or unmount operation.
    11  type mountError struct {
    12  	op     string
    13  	source string
    14  	target string
    15  	procfd string
    16  	flags  uintptr
    17  	data   string
    18  	err    error
    19  }
    20  
    21  // Error provides a string error representation.
    22  func (e *mountError) Error() string {
    23  	out := e.op + " "
    24  
    25  	if e.source != "" {
    26  		out += e.source + ":" + e.target
    27  	} else {
    28  		out += e.target
    29  	}
    30  	if e.procfd != "" {
    31  		out += " (via " + e.procfd + ")"
    32  	}
    33  
    34  	if e.flags != uintptr(0) {
    35  		out += ", flags: 0x" + strconv.FormatUint(uint64(e.flags), 16)
    36  	}
    37  	if e.data != "" {
    38  		out += ", data: " + e.data
    39  	}
    40  
    41  	out += ": " + e.err.Error()
    42  	return out
    43  }
    44  
    45  // Unwrap returns the underlying error.
    46  // This is a convention used by Go 1.13+ standard library.
    47  func (e *mountError) Unwrap() error {
    48  	return e.err
    49  }
    50  
    51  // mount is a simple unix.Mount wrapper. If procfd is not empty, it is used
    52  // instead of target (and the target is only used to add context to an error).
    53  func mount(source, target, procfd, fstype string, flags uintptr, data string) error {
    54  	dst := target
    55  	if procfd != "" {
    56  		dst = procfd
    57  	}
    58  	if err := unix.Mount(source, dst, fstype, flags, data); err != nil {
    59  		return &mountError{
    60  			op:     "mount",
    61  			source: source,
    62  			target: target,
    63  			procfd: procfd,
    64  			flags:  flags,
    65  			data:   data,
    66  			err:    err,
    67  		}
    68  	}
    69  	return nil
    70  }
    71  
    72  // unmount is a simple unix.Unmount wrapper.
    73  func unmount(target string, flags int) error {
    74  	err := unix.Unmount(target, flags)
    75  	if err != nil {
    76  		return &mountError{
    77  			op:     "unmount",
    78  			target: target,
    79  			flags:  uintptr(flags),
    80  			err:    err,
    81  		}
    82  	}
    83  	return nil
    84  }
    85  
    86  // syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
    87  // Copy from https://cs.opensource.google/go/go/+/refs/tags/go1.20.7:src/os/file_posix.go;l=61-75
    88  func syscallMode(i fs.FileMode) (o uint32) {
    89  	o |= uint32(i.Perm())
    90  	if i&fs.ModeSetuid != 0 {
    91  		o |= unix.S_ISUID
    92  	}
    93  	if i&fs.ModeSetgid != 0 {
    94  		o |= unix.S_ISGID
    95  	}
    96  	if i&fs.ModeSticky != 0 {
    97  		o |= unix.S_ISVTX
    98  	}
    99  	// No mapping for Go's ModeTemporary (plan9 only).
   100  	return
   101  }
   102  

View as plain text