Example #1
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
}
Example #2
0
File: main.go Project: 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)
	}
}
Example #3
0
func TestRootErr(t *testing.T) {
	fuse.Debugf = log.Printf
	dir, err := ioutil.TempDir("", "fusetest")
	if err != nil {
		t.Fatal(err)
	}
	os.MkdirAll(dir, 0777)

	c, err := fuse.Mount(dir)
	if err != nil {
		t.Fatal(err)
	}
	defer umount(dir)

	ch := make(chan error, 1)
	go func() {
		ch <- Serve(c, badRootFS{})
	}()

	select {
	case err := <-ch:
		if err.Error() != "cannot obtain root node: structure needs cleaning" {
			t.Errorf("Unexpected error: %v", err)
		}
	case <-time.After(1 * time.Second):
		t.Fatal("Serve did not return an error as expected, aborting")
	}
}
Example #4
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
}
Example #5
0
File: fs.go Project: rfjakob/cluefs
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
}
Example #6
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)
	}
}
Example #7
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)
	}
}
Example #8
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)
	}
}
Example #9
0
func fuseMountDir(dir string) (*fuse.Conn, error) {
	options, err := getPlatformSpecificMountOptions(dir)
	if err != nil {
		return nil, err
	}
	return fuse.Mount(dir, options...)
}
Example #10
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
}
Example #11
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
}
Example #12
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
}
Example #13
0
File: main.go Project: orivej/ghfs
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)
	}
}
Example #14
0
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
}
Example #15
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
}
Example #16
0
func (f *FS) Mount(volumeName string) error {
	log.Debugf("setting up fuse: volume=%s", volumeName)
	c, err := fuse.Mount(
		f.mountpoint,
		fuse.FSName("libsecret"),
		fuse.Subtype("libsecretfs"),
		fuse.LocalVolume(),
		fuse.VolumeName(volumeName),
	)
	if err != nil {
		return err
	}

	srv := fs.New(c, nil)

	f.server = srv
	f.volumeName = volumeName
	f.conn = c

	go func() {
		err = f.server.Serve(f)
		if err != nil {
			f.errChan <- err
		}
	}()

	// check if the mount process has an error to report
	log.Debug("waiting for mount")
	<-c.Ready
	if err := c.MountError; err != nil {
		return err
	}

	return nil
}
Example #17
0
File: fs.go Project: 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
}
Example #18
0
func NewSfs(conf *SfsConfig) (*Sfs, error) {
	sfsLogLevel = conf.LogLevel
	mnt := conf.Mountpoint
	mount_opts := getFuseMountOptions(conf)

	if !conf.Config.IsEmpty() {
		configFileOpts := readJsonFile(conf.Config)
		Echoerr("%v", configFileOpts)
	}

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

	mfs := &Sfs{
		Mountpoint: mnt,
		RootNode:   NewIdNode(conf.Paths[0]),
		Connection: c,
	}

	/** Start a goroutine which looks for INT/TERM and
	 *  calls unmount on the filesystem. Otherwise ctrl-C
	 *  leaves us with ghost mounts which outlive the process.
	 */
	trap := func(sig os.Signal) {
		Echoerr("Caught %s - forcing unmount(2) of %s\n", sig, mfs.Mountpoint)
		mfs.Unmount()
	}
	TrapExit(trap)
	return mfs, nil
}
Example #19
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)
	}
}
Example #20
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)
	}
}
Example #21
0
func TestStatfs(t *testing.T) {
	fuse.Debugf = log.Printf
	dir, err := ioutil.TempDir("", "fusetest")
	if err != nil {
		t.Fatal(err)
	}
	os.MkdirAll(dir, 0777)

	c, err := fuse.Mount(dir)
	if err != nil {
		t.Fatal(err)
	}
	defer umount(dir)

	go func() {
		err := Serve(c, testStatFS{})
		if err != nil {
			fmt.Printf("SERVE ERROR: %v\n", err)
		}
	}()

	waitForMount_inode1(t, dir)

	{
		var st syscall.Statfs_t
		err = syscall.Statfs(dir, &st)
		if err != nil {
			t.Errorf("Statfs failed: %v", err)
		}
		t.Logf("Statfs got: %#v", st)
		if g, e := st.Blocks, uint64(42); g != e {
			t.Errorf("got Blocks = %q; want %q", g, e)
		}
		if g, e := st.Namelen, int64(13); g != e {
			t.Errorf("got Namelen = %q; want %q", g, e)
		}
	}

	{
		var st syscall.Statfs_t
		f, err := os.Open(dir)
		if err != nil {
			t.Errorf("Open for fstatfs failed: %v", err)
		}
		defer f.Close()
		err = syscall.Fstatfs(int(f.Fd()), &st)
		if err != nil {
			t.Errorf("Fstatfs failed: %v", err)
		}
		t.Logf("Fstatfs got: %#v", st)
		if g, e := st.Blocks, uint64(42); g != e {
			t.Errorf("got Blocks = %q; want %q", g, e)
		}
		if g, e := st.Namelen, int64(13); g != e {
			t.Errorf("got Namelen = %q; want %q", g, e)
		}
	}

}
Example #22
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")
}
Example #23
0
// Mount makes the contents of the volume visible at the given
// mountpoint. If Mount returns with a nil error, the mount has
// occurred.
func (ref *VolumeRef) Mount(mountpoint string) error {
	ref.app.volumes.Lock()
	defer ref.app.volumes.Unlock()

	// TODO obey `bazil -debug server run`

	if ref.mounted {
		return errors.New("volume already mounted")
	}

	conn, err := fuse.Mount(mountpoint,
		fuse.MaxReadahead(32*1024*1024),
		fuse.AsyncRead(),
	)
	if err != nil {
		return fmt.Errorf("mount fail: %v", err)
	}

	srv := fusefs.New(conn, nil)
	serveErr := make(chan error, 1)
	go func() {
		defer func() {
			// remove map entry on unmount or failed mount
			ref.app.volumes.Lock()
			ref.mounted = false
			ref.conn = nil
			ref.app.volumes.Unlock()
			ref.app.volumes.Broadcast()
			ref.Close()
		}()
		defer conn.Close()
		ref.fs.SetFUSE(srv)
		defer func() {
			ref.fs.SetFUSE(nil)
		}()
		serveErr <- srv.Serve(ref.fs)
	}()

	select {
	case <-conn.Ready:
		if err := conn.MountError; err != nil {
			return fmt.Errorf("mount fail (delayed): %v", err)
		}
		ref.refs++
		ref.mounted = true
		ref.conn = conn
		ref.app.volumes.Broadcast()
		return nil
	case err := <-serveErr:
		// Serve quit early
		if err != nil {
			return fmt.Errorf("filesystem failure: %v", err)
		}
		return errors.New("Serve exited early")
	}
}
Example #24
0
func FuseMount(mountpoint string) {

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

	fs.Serve(c, NewRootDir())

}
Example #25
0
func StartFuse(manager *plugins.Manager) (*fuse.Conn, bool) {
	pluginManager = manager

	conn, err := fuse.Mount(pluginManager.Config.General.Mountpoint)
	if err != nil {
		log.Fatal(err)
		return nil, false
	}

	return conn, true
}
Example #26
0
func (m *mounter) Mount(
	mountPoint string,
	shard *pfsclient.Shard,
	commitMounts []*CommitMount,
	ready chan bool,
	debug bool,
) (retErr error) {
	var once sync.Once
	defer once.Do(func() {
		if ready != nil {
			close(ready)
		}
	})
	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
		}
	}()

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt)
	go func() {
		<-sigChan
		m.Unmount(mountPoint)
	}()

	once.Do(func() {
		if ready != nil {
			close(ready)
		}
	})
	config := &fs.Config{}
	if debug {
		config.Debug = func(msg interface{}) { lion.Printf("%+v", msg) }
	}
	if err := fs.New(conn, config).Serve(newFilesystem(m.apiClient, shard, commitMounts)); err != nil {
		return err
	}
	<-conn.Ready
	return conn.MountError
}
Example #27
0
func fuseMountDir(dir string, platformParams PlatformParams) (*fuse.Conn, error) {
	options, err := getPlatformSpecificMountOptions(dir, platformParams)
	if err != nil {
		return nil, err
	}
	c, err := fuse.Mount(dir, options...)
	if err != nil {
		err = translatePlatformSpecificError(err, platformParams)
		return nil, err
	}
	return c, nil
}
Example #28
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
}
// NewConnSrc returns a source of new connections based on Lookups in the
// provided mount directory. If there isn't a directory located at tmpdir one
// is created. The second return parameter can be used to shutdown and release
// any resources. As a result of this shutdown, or during any other fatal
// error, the returned chan will be closed.
//
// The connset parameter is optional.
func NewConnSrc(mountdir, tmpdir string, connset *proxy.ConnSet) (<-chan proxy.Conn, io.Closer, error) {
	if err := os.MkdirAll(tmpdir, 0777); err != nil {
		return nil, nil, err
	}

	if err := fuse.Unmount(mountdir); err != nil {
		// The error is too verbose to be useful to print out
	}
	log.Printf("Mounting %v...", mountdir)
	c, err := fuse.Mount(mountdir, fuse.AllowOther())
	if err != nil {
		return nil, nil, fmt.Errorf("cannot mount %q: %v", mountdir, err)
	}
	log.Printf("Mounted %v", mountdir)

	if connset == nil {
		// Make a dummy one.
		connset = proxy.NewConnSet()
	}
	conns := make(chan proxy.Conn, 1)
	root := &fsRoot{
		tmpDir:  tmpdir,
		linkDir: mountdir,
		dst:     conns,
		links:   make(map[string]symlink),
		closers: []io.Closer{c},
		connset: connset,
	}

	server := fs.New(c, &fs.Config{
		Debug: func(msg interface{}) {
			if false {
				log.Print(msg)
			}
		},
	})

	go func() {
		if err := server.Serve(root); err != nil {
			log.Printf("serve %q exited due to error: %v", mountdir, err)
		}
		// The server exited but we don't know whether this is because of a
		// graceful reason (via root.Close) or via an external force unmounting.
		// Closing the root will ensure the 'dst' chan is closed correctly to
		// signify that no new connections are possible.
		if err := root.Close(); err != nil {
			log.Printf("root.Close() error: %v", err)
		}
		log.Printf("FUSE exited")
	}()

	return conns, root, nil
}
Example #30
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
}