// umount is called exactly once to unmount this service. // note that closing the connection will not always unmount // properly. If that happens, we bring out the big guns // (mount.ForceUnmountManyTimes, exec unmount). func (m *mount) unmount() error { log.Infof("Unmounting %s", m.MountPoint()) // try unmounting with fuse lib err := fuse.Unmount(m.MountPoint()) if err == nil { return nil } log.Warningf("fuse unmount err: %s", err) // try closing the fuseConn err = m.fuseConn.Close() if err == nil { return nil } if err != nil { log.Warningf("fuse conn error: %s", err) } // try mount.ForceUnmountManyTimes if err := ForceUnmountManyTimes(m, 10); err != nil { return err } log.Infof("Seemingly unmounted %s", m.MountPoint()) return nil }
// Close unmounts the filesystem and waits for fs.Serve to return. Any // returned error will be stored in Err. It is safe to call Close // multiple times. func (mnt *Mount) Close() { if mnt.closed { return } mnt.closed = true for tries := 0; tries < 1000; tries++ { err := fuse.Unmount(mnt.Dir) if err != nil { // TODO do more than log? log.Printf("unmount error: %v", err) time.Sleep(10 * time.Millisecond) continue } break } <-mnt.done mnt.Conn.Close() os.Remove(mnt.Dir) }