github.com/vrothberg/storage@v1.12.13/drivers/devmapper/mount.go (about)

     1  // +build linux
     2  
     3  package devmapper
     4  
     5  import (
     6  	"bytes"
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"golang.org/x/sys/unix"
    12  )
    13  
    14  // FIXME: this is copy-pasted from the aufs driver.
    15  // It should be moved into the core.
    16  
    17  // Mounted returns true if a mount point exists.
    18  func Mounted(mountpoint string) (bool, error) {
    19  	var mntpointSt unix.Stat_t
    20  	if err := unix.Stat(mountpoint, &mntpointSt); err != nil {
    21  		if os.IsNotExist(err) {
    22  			return false, nil
    23  		}
    24  		return false, err
    25  	}
    26  	var parentSt unix.Stat_t
    27  	if err := unix.Stat(filepath.Join(mountpoint, ".."), &parentSt); err != nil {
    28  		return false, err
    29  	}
    30  	return mntpointSt.Dev != parentSt.Dev, nil
    31  }
    32  
    33  type probeData struct {
    34  	fsName string
    35  	magic  string
    36  	offset uint64
    37  }
    38  
    39  // ProbeFsType returns the filesystem name for the given device id.
    40  func ProbeFsType(device string) (string, error) {
    41  	probes := []probeData{
    42  		{"btrfs", "_BHRfS_M", 0x10040},
    43  		{"ext4", "\123\357", 0x438},
    44  		{"xfs", "XFSB", 0},
    45  	}
    46  
    47  	maxLen := uint64(0)
    48  	for _, p := range probes {
    49  		l := p.offset + uint64(len(p.magic))
    50  		if l > maxLen {
    51  			maxLen = l
    52  		}
    53  	}
    54  
    55  	file, err := os.Open(device)
    56  	if err != nil {
    57  		return "", err
    58  	}
    59  	defer file.Close()
    60  
    61  	buffer := make([]byte, maxLen)
    62  	l, err := file.Read(buffer)
    63  	if err != nil {
    64  		return "", err
    65  	}
    66  
    67  	if uint64(l) != maxLen {
    68  		return "", fmt.Errorf("devmapper: unable to detect filesystem type of %s, short read", device)
    69  	}
    70  
    71  	for _, p := range probes {
    72  		if bytes.Equal([]byte(p.magic), buffer[p.offset:p.offset+uint64(len(p.magic))]) {
    73  			return p.fsName, nil
    74  		}
    75  	}
    76  
    77  	return "", fmt.Errorf("devmapper: Unknown filesystem type on %s", device)
    78  }
    79  
    80  func joinMountOptions(a, b string) string {
    81  	if a == "" {
    82  		return b
    83  	}
    84  	if b == "" {
    85  		return a
    86  	}
    87  	return a + "," + b
    88  }