mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 16:34:30 +01:00
e43b5ce5e5
This is possible now that we no longer support go1.12 and brings rclone into line with standard practices in the Go world. This also removes errors.New and errors.Errorf from lib/errors and prefers the stdlib errors package over lib/errors.
79 lines
1.9 KiB
Go
79 lines
1.9 KiB
Go
//go:build linux
|
|
// +build linux
|
|
|
|
package mountlib
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/artyom/mtab"
|
|
)
|
|
|
|
const (
|
|
mtabPath = "/proc/mounts"
|
|
pollInterval = 100 * time.Millisecond
|
|
)
|
|
|
|
// CheckMountEmpty checks if folder is not already a mountpoint.
|
|
// On Linux we use the OS-specific /proc/mount 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)
|
|
}
|
|
|
|
entries, err := mtab.Entries(mtabPath)
|
|
if err != nil {
|
|
return fmt.Errorf("cannot read %s: %w", mtabPath, err)
|
|
}
|
|
for _, entry := range entries {
|
|
if entry.Dir == mountpointAbs && entry.Type != "autofs" {
|
|
return fmt.Errorf(msg, mountpointAbs)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CheckMountReady checks whether mountpoint is mounted by rclone.
|
|
// Only mounts with type "rclone" or "fuse.rclone" count.
|
|
func CheckMountReady(mountpoint string) error {
|
|
mountpointAbs, err := filepath.Abs(mountpoint)
|
|
if err != nil {
|
|
return fmt.Errorf("cannot get absolute path: %s: %w", mountpoint, err)
|
|
}
|
|
entries, err := mtab.Entries(mtabPath)
|
|
if err != nil {
|
|
return fmt.Errorf("cannot read %s: %w", mtabPath, err)
|
|
}
|
|
for _, entry := range entries {
|
|
if entry.Dir == mountpointAbs && strings.Contains(entry.Type, "rclone") {
|
|
return nil
|
|
}
|
|
}
|
|
return errors.New("mount not ready")
|
|
}
|
|
|
|
// 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
|
|
}
|