Commit 88b161f9 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Use normal umount if priviledged user.

This prevents "Failed to clone namespace" problem on some platforms.
parent c8abd57b
...@@ -8,11 +8,11 @@ import ( ...@@ -8,11 +8,11 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"syscall" "syscall"
"time"
"unsafe" "unsafe"
) )
var mountBinary string = "/bin/fusermount" var fusermountBinary string = "/bin/fusermount"
var umountBinary string = "/bin/umount"
func Socketpair(network string) (l, r *os.File, err os.Error) { func Socketpair(network string) (l, r *os.File, err os.Error) {
var domain int var domain int
...@@ -56,13 +56,13 @@ func mount(mountPoint string, options string) (f *os.File, finalMountPoint strin ...@@ -56,13 +56,13 @@ func mount(mountPoint string, options string) (f *os.File, finalMountPoint strin
mountPoint = filepath.Clean(filepath.Join(cwd, mountPoint)) mountPoint = filepath.Clean(filepath.Join(cwd, mountPoint))
} }
cmd := []string{mountBinary, mountPoint} cmd := []string{fusermountBinary, mountPoint}
if options != "" { if options != "" {
cmd = append(cmd, "-o") cmd = append(cmd, "-o")
cmd = append(cmd, options) cmd = append(cmd, options)
} }
proc, err := os.StartProcess(mountBinary, proc, err := os.StartProcess(fusermountBinary,
cmd, cmd,
&os.ProcAttr{ &os.ProcAttr{
Env: []string{"_FUSE_COMMFD=3"}, Env: []string{"_FUSE_COMMFD=3"},
...@@ -86,28 +86,27 @@ func mount(mountPoint string, options string) (f *os.File, finalMountPoint strin ...@@ -86,28 +86,27 @@ func mount(mountPoint string, options string) (f *os.File, finalMountPoint strin
} }
func privilegedUnmount(mountPoint string) os.Error { func privilegedUnmount(mountPoint string) os.Error {
maxTry := 2 dir, _ := filepath.Split(mountPoint)
delay := int64(0) proc, err := os.StartProcess(umountBinary,
[]string{umountBinary, mountPoint},
errNo := syscall.Unmount(mountPoint, 0) &os.ProcAttr{Dir: dir, Files: []*os.File{nil, nil, os.Stderr}})
for try := 0; errNo != 0 && try < maxTry; try++ { if err != nil {
// A file close operation must be processed and acked return err
// by the daemon. This takes some time, so retry if }
// the first unmount fails. w, err := os.Wait(proc.Pid, 0)
delay = 2*delay + 0.01e9 if w.ExitStatus() != 0 {
time.Sleep(delay) return os.NewError(fmt.Sprintf("umount exited with code %d\n", w.ExitStatus()))
errNo = syscall.Unmount(mountPoint, 0) }
} return err
if errNo == 0 {
return nil
}
return os.Errno(errNo)
} }
func unmount(mountPoint string) (err os.Error) { func unmount(mountPoint string) (err os.Error) {
if os.Geteuid() == 0 {
return privilegedUnmount(mountPoint)
}
dir, _ := filepath.Split(mountPoint) dir, _ := filepath.Split(mountPoint)
proc, err := os.StartProcess(mountBinary, proc, err := os.StartProcess(fusermountBinary,
[]string{mountBinary, "-u", mountPoint}, []string{fusermountBinary, "-u", mountPoint},
&os.ProcAttr{Dir: dir, Files: []*os.File{nil, nil, os.Stderr}}) &os.ProcAttr{Dir: dir, Files: []*os.File{nil, nil, os.Stderr}})
if err != nil { if err != nil {
return return
...@@ -156,10 +155,18 @@ func getConnection(local *os.File) (f *os.File, err os.Error) { ...@@ -156,10 +155,18 @@ func getConnection(local *os.File) (f *os.File, err os.Error) {
func init() { func init() {
for _, v := range strings.Split(os.Getenv("PATH"), ":") { for _, v := range strings.Split(os.Getenv("PATH"), ":") {
tpath := path.Join(v, "fusermount") tpath := path.Join(v, "fusermount")
fi, err := os.Stat(tpath) fi, _ := os.Stat(tpath)
if err == nil && (fi.Mode&0111) != 0 { if fi != nil && (fi.Mode&0111) != 0 {
mountBinary = tpath fusermountBinary = tpath
break
}
tpath = path.Join(v, "umount")
fi, _ = os.Stat(tpath)
if fi != nil && (fi.Mode&0111) != 0 {
umountBinary = tpath
break break
} }
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment