mirror of
https://github.com/restic/restic.git
synced 2026-06-18 06:34:18 +00:00
Merge pull request #21876 from MichaelEischer/cleanup-mount-validation
mount: refactor mountpoint validation
This commit is contained in:
+31
-28
@@ -134,36 +134,9 @@ func runMount(ctx context.Context, opts MountOptions, gopts global.Options, args
|
||||
}
|
||||
|
||||
mountpoint := args[0]
|
||||
|
||||
// Check the existence of the mount point at the earliest stage to
|
||||
// prevent unnecessary computations while opening the repository.
|
||||
stat, err := os.Stat(mountpoint)
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
printer.P("Mountpoint %s doesn't exist", mountpoint)
|
||||
return errors.Fatal("invalid mountpoint")
|
||||
} else if !stat.IsDir() {
|
||||
printer.P("Mountpoint %s is not a directory", mountpoint)
|
||||
return errors.Fatal("invalid mountpoint")
|
||||
}
|
||||
|
||||
err = unix.Access(mountpoint, unix.W_OK|unix.X_OK)
|
||||
if err != nil {
|
||||
printer.P("Mountpoint %s is not writeable or not executable", mountpoint)
|
||||
return errors.Fatal("inaccessible mountpoint")
|
||||
}
|
||||
|
||||
// Refuse to mount onto (or under, or over) the local repository directory.
|
||||
// Doing so makes the FUSE server read its own backend files through the
|
||||
// mount it just created, deadlocking the kernel (GH #5234).
|
||||
loc, err := location.Parse(gopts.Backends, gopts.Repo)
|
||||
if err != nil {
|
||||
if err := validateMountpoint(mountpoint, gopts); err != nil {
|
||||
return err
|
||||
}
|
||||
if loc.Scheme == "local" {
|
||||
if err := checkMountpointOverlap(loc.Config.(*local.Config).Path, mountpoint); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
debug.Log("start mount")
|
||||
defer debug.Log("finish mount")
|
||||
@@ -247,6 +220,36 @@ func runMount(ctx context.Context, opts MountOptions, gopts global.Options, args
|
||||
return err
|
||||
}
|
||||
|
||||
func validateMountpoint(mountpoint string, gopts global.Options) error {
|
||||
// Check the existence of the mount point at the earliest stage to
|
||||
// prevent unnecessary computations while opening the repository.
|
||||
stat, err := os.Stat(mountpoint)
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return errors.Fatal(fmt.Sprintf("mountpoint %s does not exist", mountpoint))
|
||||
} else if !stat.IsDir() {
|
||||
return errors.Fatal(fmt.Sprintf("mountpoint %s is not a directory", mountpoint))
|
||||
}
|
||||
|
||||
err = unix.Access(mountpoint, unix.W_OK|unix.X_OK)
|
||||
if err != nil {
|
||||
return errors.Fatal(fmt.Sprintf("mountpoint %s is not writeable or not executable", mountpoint))
|
||||
}
|
||||
|
||||
// Refuse to mount onto (or under, or over) the local repository directory.
|
||||
// Doing so makes the FUSE server read its own backend files through the
|
||||
// mount it just created, deadlocking the kernel (GH #5234).
|
||||
loc, err := location.Parse(gopts.Backends, gopts.Repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if loc.Scheme == "local" {
|
||||
if err := checkMountpointOverlap(loc.Config.(*local.Config).Path, mountpoint); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkMountpointOverlap returns an error.Fatal if the local repository at
|
||||
// repoPath and the mountpoint overlap: equal paths, mountpoint nested inside
|
||||
// the repo, or the repo nested inside the mountpoint. Any overlap deadlocks
|
||||
|
||||
Reference in New Issue
Block a user