diff --git a/README.md b/README.md index 9ef980b..7f94901 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Read-only FUSE mount that exposes Kubernetes container filesystems locally. ```bash # uses the current kubeconfig context -$ vifal /mnt/foo-cluster & +$ vifal /mnt/foo-cluster 2>/tmp/vifal.log & $ ls /mnt/foo-cluster/ default kube-system monitoring apps diff --git a/e2e/tests/zz_mount.sh b/e2e/tests/zz_mount.sh index 7cd9622..f964ffb 100644 --- a/e2e/tests/zz_mount.sh +++ b/e2e/tests/zz_mount.sh @@ -41,10 +41,8 @@ check_clean_unmount "$MOUNT" remount sigint -if [ "$UNAME_S" != "Darwin" ]; then - log_step "double mount fails" - must_fail "$VIFAL" $DEBUG "$MOUNT" -fi +log_step "double mount fails" +must_fail "$VIFAL" $DEBUG "$MOUNT" log_step "SIGINT unmount" kill -INT "$VIFAL_PID" diff --git a/main.go b/main.go index df04023..e612a34 100644 --- a/main.go +++ b/main.go @@ -139,6 +139,9 @@ Flags: } fuseMountpoint = pflag.Arg(0) + if isMountpoint(fuseMountpoint) { + logger.Fatalf("%s is already a mountpoint", fuseMountpoint) + } server, err := fs.Mount(fuseMountpoint, root, &fs.Options{ MountOptions: fuse.MountOptions{ Name: *fsName, @@ -277,6 +280,20 @@ Flags: } } +// isMountpoint reports whether path is already a mountpoint by comparing +// device IDs with its parent (different device = mount boundary). +// TODO: This should probably be more cleanly handled by go-fuse. +func isMountpoint(path string) bool { + var st, pst syscall.Stat_t + if err := syscall.Stat(path, &st); err != nil { + return false + } + if err := syscall.Stat(filepath.Dir(path), &pst); err != nil { + return false + } + return st.Dev != pst.Dev +} + // doUnmount tries platform-appropriate unmount commands in order. func doUnmount(mountpoint string, force bool) error { cmds := [][]string{{"fusermount", "-u", mountpoint}, {"umount", mountpoint}}