78 lines · 2.0 KB · Go
RawDownload
//go:build linux package mountlib import (	"fmt"	"path/filepath"	"strings" 	"github.com/moby/sys/mountinfo") // CheckMountEmpty checks if folder is not already a mountpoint.// On Linux we use the OS-specific /proc/self/mountinfo API so the check won't access the path.// Directories marked as "mounted" by autofs are considered not mounted.func CheckMountEmpty(mountpoint string) error {	const msg = "directory already mounted, use --allow-non-empty to mount anyway: %s" 	mountpointAbs, err := filepath.Abs(mountpoint)	if err != nil {		return fmt.Errorf("cannot get absolute path: %s: %w", mountpoint, err)	} 	infos, err := mountinfo.GetMounts(mountinfo.SingleEntryFilter(mountpointAbs))	if err != nil {		return fmt.Errorf("cannot get mounts: %w", err)	} 	foundAutofs := false	for _, info := range infos {		if info.FSType != "autofs" {			return fmt.Errorf(msg, mountpointAbs)		}		foundAutofs = true	}	// It isn't safe to list an autofs in the middle of mounting	if foundAutofs {		return nil	} 	return checkMountEmpty(mountpoint)} // singleEntryFilter looks for a specific entry.//// It may appear more than once and we return all of them if so.func singleEntryFilter(mp string) mountinfo.FilterFunc {	return func(m *mountinfo.Info) (skip, stop bool) {		return m.Mountpoint != mp, false	}} // CheckMountReady checks whether mountpoint is mounted by rclone.// Only mounts with type "rclone" or "fuse.rclone" count.func CheckMountReady(mountpoint string) error {	const msg = "mount not ready: %s" 	mountpointAbs, err := filepath.Abs(mountpoint)	if err != nil {		return fmt.Errorf("cannot get absolute path: %s: %w", mountpoint, err)	} 	infos, err := mountinfo.GetMounts(singleEntryFilter(mountpointAbs))	if err != nil {		return fmt.Errorf("cannot get mounts: %w", err)	} 	for _, info := range infos {		if strings.Contains(info.FSType, "rclone") {			return nil		}	} 	return fmt.Errorf(msg, mountpointAbs)} // CanCheckMountReady is set if CheckMountReady is functionalvar CanCheckMountReady = true