mirror of
https://github.com/restic/restic.git
synced 2026-08-03 20:52:16 +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]
|
mountpoint := args[0]
|
||||||
|
if err := validateMountpoint(mountpoint, gopts); err != nil {
|
||||||
// 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 {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if loc.Scheme == "local" {
|
|
||||||
if err := checkMountpointOverlap(loc.Config.(*local.Config).Path, mountpoint); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug.Log("start mount")
|
debug.Log("start mount")
|
||||||
defer debug.Log("finish mount")
|
defer debug.Log("finish mount")
|
||||||
@@ -247,6 +220,36 @@ func runMount(ctx context.Context, opts MountOptions, gopts global.Options, args
|
|||||||
return err
|
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
|
// checkMountpointOverlap returns an error.Fatal if the local repository at
|
||||||
// repoPath and the mountpoint overlap: equal paths, mountpoint nested inside
|
// repoPath and the mountpoint overlap: equal paths, mountpoint nested inside
|
||||||
// the repo, or the repo nested inside the mountpoint. Any overlap deadlocks
|
// the repo, or the repo nested inside the mountpoint. Any overlap deadlocks
|
||||||
|
|||||||
Reference in New Issue
Block a user