Beispiel #1
0
Datei: main.go Projekt: pjq/ghfs
func main() {
	flag.Parse()

	if *token == "" {
		log.Println("must provide -token")
		os.Exit(1)
	}
	client = github.NewClient(oauth2.NewClient(oauth2.NoContext, oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: *token},
	)))

	if *mountpoint == "" {
		log.Println("must provide -mountpoint")
		os.Exit(1)
	}
	c, err := fuse.Mount(*mountpoint)
	if err != nil {
		log.Printf("mount: %v", err)
		os.Exit(1)
	}
	defer c.Close()

	log.Println("serving...")
	if err := fs.Serve(c, FS{}); err != nil {
		log.Printf("serve: %v", err)
		os.Exit(1)
	}

	<-c.Ready
	if err := c.MountError; err != nil {
		log.Printf("mount error: %v", err)
		os.Exit(1)
	}
}
Beispiel #2
0
func runMount(cmd *Command, args []string) bool {
	fmt.Printf("This is SeaweedFS version %s %s %s\n", util.VERSION, runtime.GOOS, runtime.GOARCH)
	if *mountOptions.dir == "" {
		fmt.Printf("Please specify the mount directory via \"-dir\"")
		return false
	}

	c, err := fuse.Mount(*mountOptions.dir)
	if err != nil {
		glog.Fatal(err)
		return false
	}

	OnInterrupt(func() {
		fuse.Unmount(*mountOptions.dir)
		c.Close()
	})

	err = fs.Serve(c, WFS{})
	if err != nil {
		fuse.Unmount(*mountOptions.dir)
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		glog.Fatal(err)
	}

	return true
}
Beispiel #3
0
func main() {
	flag.Usage = Usage
	flag.Parse()

	if flag.NArg() != 1 {
		Usage()
		os.Exit(2)
	}
	mountpoint := flag.Arg(0)

	c, err := fuse.Mount(mountpoint)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	err = fs.Serve(c, FS{})
	if err != nil {
		log.Fatal(err)
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		log.Fatal(err)
	}
}
Beispiel #4
0
func mount(dbpath, mountpoint string) error {
	db, err := bolt.Open(dbpath, 0600, nil)
	if err != nil {
		return err
	}

	c, err := fuse.Mount(mountpoint)
	if err != nil {
		return err
	}
	defer c.Close()

	filesys := &FS{
		db: db,
	}
	if err := fs.Serve(c, filesys); err != nil {
		return err
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		return err
	}

	return nil
}
Beispiel #5
0
// Mount mounts an IpfsNode instance at a particular path. It
// serves until the process receives exit signals (to Unmount).
func Mount(ipfs *core.IpfsNode, fpath string) error {

	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
		syscall.SIGTERM, syscall.SIGQUIT)

	go func() {
		<-sigc
		Unmount(fpath)
	}()

	c, err := fuse.Mount(fpath)
	if err != nil {
		return err
	}
	defer c.Close()

	err = fs.Serve(c, FileSystem{Ipfs: ipfs})
	if err != nil {
		return err
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		return err
	}
	return nil
}
Beispiel #6
0
func (m *mounter) Mount(
	address string,
	mountPoint string,
	shard uint64,
	modulus uint64,
) (retErr error) {
	// TODO: should we make the caller do this?
	if err := os.MkdirAll(mountPoint, 0777); err != nil {
		return err
	}
	name := namePrefix + address
	conn, err := fuse.Mount(
		mountPoint,
		fuse.FSName(name),
		fuse.VolumeName(name),
		fuse.Subtype(subtype),
		fuse.AllowOther(),
		fuse.WritebackCache(),
		fuse.MaxReadahead(1<<32-1),
	)
	if err != nil {
		return err
	}
	defer func() {
		if err := conn.Close(); err != nil && retErr == nil {
			retErr = err
		}
	}()
	if err := fs.Serve(conn, newFilesystem(m.apiClient, shard, modulus)); err != nil {
		return err
	}
	<-conn.Ready
	return conn.MountError
}
Beispiel #7
0
func main() {
	ufs := unitefs.NewFS()

	for i := 1; i < len(os.Args)-1; i++ {
		println(os.Args[i])
		ufs.RegisterSubtree(os.Args[i])
	}

	c, err := fuse.Mount(
		os.Args[len(os.Args)-1],
		fuse.FSName("unitefs"),
		fuse.Subtype("unitefs"),
		fuse.LocalVolume(),
		fuse.VolumeName("unitefs"),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	fmt.Println("FS mounted")

	err = fs.Serve(c, ufs)
	if err != nil {
		log.Fatal(err)
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		log.Fatal(err)
	}
}
Beispiel #8
0
func main() {
	log.SetFlags(0)

	// Parse arguments and require that we have the path.
	token := flag.String("token", "", "personal access token")
	flag.Parse()
	if flag.NArg() != 1 {
		log.Fatal("path required")
	}
	log.Printf("mounting to: %s", flag.Arg(0))

	// Create FUSE connection.
	conn, err := fuse.Mount(flag.Arg(0))
	if err != nil {
		log.Fatal(err)
	}

	// Create OAuth transport.
	var c *http.Client
	if *token != "" {
		c = (&oauth.Transport{Token: &oauth.Token{AccessToken: *token}}).Client()
	}

	// Create filesystem.
	filesys := &FS{Client: github.NewClient(c)}
	if err := fs.Serve(conn, filesys); err != nil {
		log.Fatal(err)
	}

	// Wait until the mount is unmounted or there is an error.
	<-conn.Ready
	if err := conn.MountError; err != nil {
		log.Fatal(err)
	}
}
Beispiel #9
0
func (fs *ClueFS) MountAndServe(mountpoint string, readonly bool) error {
	// Mount the file system
	fs.mountDir = mountpoint
	if IsDebugActive() {
		fuse.Debug = FuseDebug
	}
	mountOpts := []fuse.MountOption{
		fuse.FSName(programName),
		fuse.Subtype(programName),
		fuse.VolumeName(programName),
		fuse.LocalVolume(),
	}
	if readonly {
		mountOpts = append(mountOpts, fuse.ReadOnly())
	}
	conn, err := fuse.Mount(mountpoint, mountOpts...)
	if err != nil {
		return err
	}
	defer conn.Close()

	// Start serving requests
	if err = fusefs.Serve(conn, fs); err != nil {
		return err
	}

	// Check for errors when mounting the file system
	<-conn.Ready
	if err = conn.MountError; err != nil {
		return err
	}

	return nil
}
Beispiel #10
0
func Mount(host, mountpoint string) error {
	conn, err := net.Dial("tcp", host)
	if err != nil {
		return err
	}
	defer conn.Close()
	log.Println("Connected")

	c, err := fuse.Mount(
		mountpoint,
		fuse.FSName("simple-network-fuse"),
		fuse.Subtype("rofl"),
	)
	if err != nil {
		return err
	}
	defer c.Close()

	fsConn := connection{
		enc: gob.NewEncoder(conn),
		dec: gob.NewDecoder(conn),
	}

	err = fs.Serve(c, &FS{fsConn})
	if err != nil {
		return err
	}

	<-c.Ready
	if err := c.MountError; err != nil {
		return err
	}
	return nil
}
Beispiel #11
0
Datei: fs.go Projekt: ncw/rclone
// mount the file system
//
// The mount point will be ready when this returns.
//
// returns an error, and an error channel for the serve process to
// report an error when fusermount is called.
func mount(f fs.Fs, mountpoint string) (<-chan error, error) {
	fs.Debug(f, "Mounting on %q", mountpoint)
	c, err := fuse.Mount(mountpoint, mountOptions(f.Name()+":"+f.Root())...)
	if err != nil {
		return nil, err
	}

	filesys := &FS{
		f: f,
	}

	// Serve the mount point in the background returning error to errChan
	errChan := make(chan error, 1)
	go func() {
		err := fusefs.Serve(c, filesys)
		closeErr := c.Close()
		if err == nil {
			err = closeErr
		}
		errChan <- err
	}()

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		return nil, err
	}

	return errChan, nil
}
Beispiel #12
0
func main() {
	flag.Usage = usage
	flag.Parse()

	if flag.NArg() != 1 {
		usage()
		os.Exit(2)
	}
	mountpoint := flag.Arg(0)

	c, err := fuse.Mount(
		mountpoint,
		fuse.FSName("helloworld"),
		fuse.Subtype("hellofs"),
		fuse.LocalVolume(),
		fuse.VolumeName("Hello world!"),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	err = fs.Serve(c, FS{})
	if err != nil {
		log.Fatal(err)
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		log.Fatal(err)
	}
}
Beispiel #13
0
func Run(c *cli.Context) {
	println("Amazon Cloud Drive mount at", c.String("mountpoint"))
	mountpoint := c.String("mountpoint")
	if mountpoint == "" {
		log.Fatal("no mountpoint! try running \"acdfuse help\"")
	}

	fuseCtx, err := fuse.Mount(
		c.String("mountpoint"),
		fuse.FSName("helloworld"),
		fuse.Subtype("hellofs"),
		fuse.LocalVolume(),
		fuse.VolumeName("Hello world!"),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer fuseCtx.Close()

	err = fs.Serve(fuseCtx, acdfs.FS{})
	if err != nil {
		log.Fatal(err)
	}

	// check if the mount process has an error to report
	<-fuseCtx.Ready
	if err := fuseCtx.MountError; err != nil {
		log.Fatal(err)
	}
}
Beispiel #14
0
func main() {

	MIRROR_FOLDER := "/Users/ryanstout/Sites/infinitydrive/go/drive"

	flag.Usage = Usage
	flag.Parse()

	if flag.NArg() != 1 {
		Usage()
		os.Exit(2)
	}
	mountpoint := flag.Arg(0)

	c, err := fuse.Mount(mountpoint)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	err = fs.Serve(c, FS{MIRROR_FOLDER})
	if err != nil {
		log.Fatal(err)
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		log.Fatal(err)
	}
}
Beispiel #15
0
func (m *mounter) Mount(apiClient pfs.ApiClient, repositoryName string, mountPoint string, shard uint64, modulus uint64) (retErr error) {
	if err := os.MkdirAll(mountPoint, 0777); err != nil {
		return err
	}
	conn, err := fuse.Mount(
		mountPoint,
		fuse.FSName(namePrefix+repositoryName),
		fuse.VolumeName(namePrefix+repositoryName),
		fuse.Subtype(subtype),
		fuse.WritebackCache(),
		fuse.MaxReadahead(1<<32-1),
	)
	if err != nil {
		return err
	}
	defer func() {
		if err := conn.Close(); err != nil && retErr == nil {
			retErr = err
		}
	}()
	close(m.ready)
	if err := fs.Serve(conn, &filesystem{apiClient, repositoryName, shard, modulus}); err != nil {
		return err
	}

	// check if the mount process has an error to report
	<-conn.Ready
	return conn.MountError
}
func (v *volumeDriver) Mount(volumeID api.VolumeID, mountpath string) error {
	volume, err := v.GetVol(volumeID)
	if err != nil {
		return err
	}
	mountOptions, err := v.provider.GetMountOptions(volume.Spec)
	if err != nil {
		return err
	}
	conn, err := fuse.Mount(mountpath, mountOptions...)
	if err != nil {
		return err
	}
	filesystem, err := v.provider.GetFS(volume.Spec)
	if err != nil {
		return err
	}
	go func() {
		// TODO: track error once we understand driver model better
		_ = fs.Serve(conn, filesystem)
		_ = conn.Close()
	}()
	<-conn.Ready
	return conn.MountError
}
Beispiel #17
0
func main() {
	var err error

	// getopt
	flag.Usage = usage
	flag.Parse()
	if flag.NArg() != 2 {
		usage()
		os.Exit(2)
	}
	mountpoint := flag.Arg(0)
	snmpServer := flag.Arg(1)

	// connect snmp
	snmp.client, err = gosnmp.NewGoSNMP(snmpServer, "public", gosnmp.Version2c, 5)
	if err != nil {
		logrus.Fatalf("gosnmp.NewGoSNMP: %v", err)
	}
	//snmp.client.SetDebug(true)
	//snmp.client.SetVerbose(true)
	snmp.currentId = 1
	snmp.cache = make(map[string]SnmpCacheEntry)
	snmp.cacheMap = make(map[uint64]string)

	// preload initial cache
	err = snmp.LoadWalk(".1.3.6.1")
	if err != nil {
		logrus.Fatalf("snmp.LoadWalk: %v", err)
	}

	// mount fuse
	c, err := fuse.Mount(
		mountpoint,
		fuse.FSName("fuse-snmp"),
		fuse.Subtype("snmpfs"),
		fuse.LocalVolume(),
		fuse.VolumeName("Fuse SNMP"),
	)
	if err != nil {
		logrus.Fatalf("fuse.Mount: %v", err)
	}
	defer c.Close()

	// map fuse
	err = fs.Serve(c, FS{})
	if err != nil {
		logrus.Fatalf("fs.Serve: %v", err)
	}

	// wait for fuse close
	<-c.Ready
	if err := c.MountError; err != nil {
		logrus.Fatalf("c.MountError: %v", err)
	}

	logrus.Fatalf("BYEBYE")
}
Beispiel #18
0
func FuseMount(mountpoint string) {

	c, err := fuse.Mount(mountpoint)
	if err != nil {
		log.Fatal(err)
	}

	fs.Serve(c, NewRootDir())

}
Beispiel #19
0
// OpenFUSE mounts the given directory as a FUSE file system.
// The FUSE system is a singleton with only one FUSE server operable.
func OpenFUSE(dir string, data Mountable, vinfo VersionInfo) error {
	fuseServer.mutex.Lock()
	defer fuseServer.mutex.Unlock()

	// Make sure we haven't switched mount directory.
	if len(fuseServer.dir) > 0 {
		if fuseServer.dir != dir {
			return fmt.Errorf("Cannot open more than one FUSE directory.  Currently open: %s\n",
				fuseServer.dir)
		}
	}

	// Make sure our mount directory is present and a directory.
	finfo, err := os.Stat(dir)
	if err != nil {
		if os.IsNotExist(err) {
			if err = os.MkdirAll(dir, 0744); err != nil {
				return fmt.Errorf("Cannot create mount directory: %s (%s)\n",
					dir, err.Error())
			}
		} else {
			return fmt.Errorf("Cannot access given mount directory: %s\n", dir)
		}
	} else if !finfo.IsDir() {
		return fmt.Errorf("Given mount point (%s) is not a directory\n", dir)
	}

	// Check if data is already mounted at this version.
	mount, found := fuseServer.mounts[vinfo.uuid]
	if found {
		mount.AddData(data, vinfo)
		return nil
	}

	fuseServer.mounts[vinfo.uuid] = Mount{Data{data}, vinfo}

	// Mount and serve if not already served.
	if fuseServer.dir == "" {
		fuseServer.dir = dir
		conn, err := fuse.Mount(dir)
		if err != nil {
			return err
		}

		// Run FUSE system in gothread.
		go func() {
			dvid.StartCgo()
			fs.Serve(conn, fuseServer)
			dvid.StopCgo()
		}()
	}
	return nil
}
Beispiel #20
0
func (d *DumbDestiny) CreateFS(mountpoint string) (*fs.FS, chan struct{}, error) {
	conn, err := fuse.Mount(mountpoint)
	if err != nil {
		return nil, nil, err
	}
	f := fs.NewFS()
	done := make(chan struct{})
	go func(done chan struct{}) {
		fsup.Serve(conn, f)
		done <- struct{}{}
	}(done)
	return f, done, nil
}
Beispiel #21
0
func main() {
	flag.Usage = Usage
	flag.Parse()

	if flag.NArg() != 2 {
		Usage()
		os.Exit(2)
	}
	mountpoint := flag.Arg(0)

	c, err := fuse.Mount(
		mountpoint,
		fuse.FSName("MomFS"),
		fuse.Subtype("momfs"),
		fuse.LocalVolume(),
		fuse.VolumeName("Mom file system"),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	sigintCh := make(chan os.Signal, 1)
	signal.Notify(sigintCh, os.Interrupt)

	go func() {
		<-sigintCh
		log.Printf("Program interrupted. Trying to unmount file system.\n")
		err := fuse.Unmount(mountpoint)
		if err != nil {
			log.Println(err)
			log.Println("Failed to unmount file system. Trying again..")
			for {
				<-time.Tick(1 * time.Second)
				fuse.Unmount(mountpoint)
			}
		}
	}()

	err = fs.Serve(c, NewOrgFS())
	if err != nil {
		log.Fatal(err)
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		log.Fatal(err)
	}
}
Beispiel #22
0
// Mount does not block.  It's up to the caller to block by reading on a channel, etc.
func Mount(mountpoint string, b Backend) (io.Closer, error) {
	var perm os.FileMode = 0644
	if err := os.MkdirAll(mountpoint, perm); err != nil {
		return nil, err
	}

	c, err := fuse.Mount(mountpoint)
	if err != nil {
		return nil, err
	}

	go func() {
		fs.Serve(c, &FS{backend: b})
	}()
	return &handle{conn: c}, nil
}
Beispiel #23
0
// Mount the FS at the given mountpoint
func (v *VaultFS) Mount() error {
	var err error
	v.conn, err = fuse.Mount(
		v.mountpoint,
		fuse.FSName("vault"),
		fuse.VolumeName("vault"),
	)

	logrus.Debug("created conn")
	if err != nil {
		return err
	}

	logrus.Debug("starting to serve")
	return fs.Serve(v.conn, v)
}
Beispiel #24
0
func (m *mounter) Mount(
	repositoryName string,
	commitID string,
	mountPoint string,
	shard uint64,
	modulus uint64,
) (retErr error) {
	// TODO(pedge): should we make the caller do this?
	if err := os.MkdirAll(mountPoint, 0777); err != nil {
		return err
	}
	name := namePrefix + repositoryName
	if commitID != "" {
		name = name + "-" + commitID
	}
	conn, err := fuse.Mount(
		mountPoint,
		fuse.FSName(name),
		fuse.VolumeName(name),
		fuse.Subtype(subtype),
		fuse.AllowOther(),
		fuse.WritebackCache(),
		fuse.MaxReadahead(1<<32-1),
	)
	if err != nil {
		return err
	}
	errChan := make(chan error, 1)
	m.lock.Lock()
	if _, ok := m.mountpointToErrChan[mountPoint]; ok {
		m.lock.Unlock()
		return fmt.Errorf("mountpoint %s already exists", mountPoint)
	}
	m.mountpointToErrChan[mountPoint] = errChan
	m.lock.Unlock()
	go func() {
		err := fs.Serve(conn, newFilesystem(m.apiClient, repositoryName, commitID, shard, modulus))
		closeErr := conn.Close()
		if err != nil {
			errChan <- err
		} else {
			errChan <- closeErr
		}
	}()
	<-conn.Ready
	return conn.MountError
}
Beispiel #25
0
func main() {
	flag.Usage = Usage
	flag.Parse()

	if flag.NArg() != 1 {
		Usage()
		os.Exit(2)
	}
	mountpoint := flag.Arg(0)

	c, err := fuse.Mount(mountpoint)
	if err != nil {
		log.Fatal(err)
	}

	fs.Serve(c, FS{})
}
Beispiel #26
0
func MountFuse(mountpoint string, m *model.Model) {
	c, err := fuse.Mount(
		mountpoint,
		fuse.FSName("syncthingfuse"),
		fuse.Subtype("syncthingfuse"),
		fuse.LocalVolume(),
		fuse.VolumeName("Syncthing FUSE"),
	)
	if err != nil {
		l.Warnln(err)
	}

	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)

	doneServe := make(chan error, 1)
	go func() {
		doneServe <- fs.Serve(c, FS{m: m})
	}()

	select {
	case err := <-doneServe:
		l.Infoln("conn.Serve returned", err)

		// check if the mount process has an error to report
		<-c.Ready
		if err := c.MountError; err != nil {
			l.Warnln("conn.MountError:", err)
		}
	case sig := <-sigc:
		l.Infoln("Signal", sig, "received, shutting down.")
	}

	time.AfterFunc(3*time.Second, func() {
		os.Exit(1)
	})
	l.Infoln("Unmounting...")
	err = Unmount(mountpoint)
	if err == nil {
		l.Infoln("Unmounted")
	} else {
		l.Infoln("Unmount failed:", err)
	}

	l.Infoln("syncthing FUSE process ending.")
}
Beispiel #27
0
func (m *mounter) Mount(
	mountPoint string,
	shard *pfs.Shard,
	commitMounts []*CommitMount,
	ready chan bool,
) (retErr error) {
	var once sync.Once
	defer once.Do(func() {
		if ready != nil {
			close(ready)
		}
	})
	// TODO: should we make the caller do this?
	if err := os.MkdirAll(mountPoint, 0777); err != nil {
		return err
	}
	name := namePrefix + m.address
	conn, err := fuse.Mount(
		mountPoint,
		fuse.FSName(name),
		fuse.VolumeName(name),
		fuse.Subtype(subtype),
		fuse.AllowOther(),
		fuse.WritebackCache(),
		fuse.MaxReadahead(1<<32-1),
	)
	if err != nil {
		return err
	}
	defer func() {
		if err := conn.Close(); err != nil && retErr == nil {
			retErr = err
		}
	}()
	once.Do(func() {
		if ready != nil {
			close(ready)
		}
	})
	if err := fs.Serve(conn, newFilesystem(m.apiClient, shard, commitMounts)); err != nil {
		return err
	}
	<-conn.Ready
	return conn.MountError
}
Beispiel #28
0
func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error {
	debug.Log("start mount")
	defer debug.Log("finish mount")

	repo, err := OpenRepository(gopts)
	if err != nil {
		return err
	}

	err = repo.LoadIndex()
	if err != nil {
		return err
	}

	if _, err := resticfs.Stat(mountpoint); os.IsNotExist(errors.Cause(err)) {
		Verbosef("Mountpoint %s doesn't exist, creating it\n", mountpoint)
		err = resticfs.Mkdir(mountpoint, os.ModeDir|0700)
		if err != nil {
			return err
		}
	}
	c, err := systemFuse.Mount(
		mountpoint,
		systemFuse.ReadOnly(),
		systemFuse.FSName("restic"),
	)
	if err != nil {
		return err
	}

	Printf("Now serving the repository at %s\n", mountpoint)
	Printf("Don't forget to umount after quitting!\n")

	root := fs.Tree{}
	root.Add("snapshots", fuse.NewSnapshotsDir(repo, opts.OwnerRoot))

	debug.Log("serving mount at %v", mountpoint)
	err = fs.Serve(c, &root)
	if err != nil {
		return err
	}

	<-c.Ready
	return c.MountError
}
Beispiel #29
0
func (f *FS) MountAndServe(dir string) error {
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		err = os.MkdirAll(dir, os.ModeDir|0777)
		if err != nil {
			return err
		}
	} else if err != nil {
		return err
	}
	conn, err := fuse.Mount(dir)
	if err != nil {
		println("mount failed", err.Error())
		return err
	}
	// FIXME: error handling there
	go fs.Serve(conn, f)
	return nil
}
Beispiel #30
0
func ServeFUSE(bucketName string, mountpoint string, ofs *otaru.FileSystem, ready chan<- bool) error {
	fsName := fmt.Sprintf("otaru+gs://%s", bucketName)
	volName := fmt.Sprintf("Otaru %s", bucketName)

	c, err := bfuse.Mount(
		mountpoint,
		bfuse.FSName(fsName),
		bfuse.Subtype("otarufs"),
		bfuse.VolumeName(volName),
	)
	if err != nil {
		return fmt.Errorf("bfuse.Mount failed: %v", err)
	}
	defer c.Close()

	serveC := make(chan error)
	go func() {
		if err := bfs.Serve(c, FileSystem{ofs}); err != nil {
			serveC <- err
			close(serveC)
			return
		}
		close(serveC)
	}()

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		return err
	}

	logger.Infof(mylog, "Mountpoint \"%s\" should be ready now!", mountpoint)
	if ready != nil {
		close(ready)
	}

	if err := <-serveC; err != nil {
		return nil
	}
	if err := ofs.Sync(); err != nil {
		return fmt.Errorf("Failed to Sync fs: %v", err)
	}
	return nil
}