Anagh Kumar Baranwalfix: mount parsing for linuxbb0cd763 years agoHistory
89 lines · 2.1 KB · Go
RawDownload
//go:build linux// +build linux package mountlib import (	"fmt"	"path/filepath"	"strings"	"time" 	"github.com/moby/sys/mountinfo") const (	pollInterval = 100 * time.Millisecond) // 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)} // 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(mountinfo.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)} // WaitMountReady waits until mountpoint is mounted by rclone.func WaitMountReady(mountpoint string, timeout time.Duration) (err error) {	endTime := time.Now().Add(timeout)	for {		err = CheckMountReady(mountpoint)		delay := time.Until(endTime)		if err == nil || delay <= 0 {			break		}		if delay > pollInterval {			delay = pollInterval		}		time.Sleep(delay)	}	return}