Пример #1
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("clock"),
		fuse.Subtype("clockfsfs"),
		fuse.LocalVolume(),
		fuse.VolumeName("Clock filesystem"),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	srv := fs.New(c, nil)
	filesys := &FS{
		// We pre-create the clock node so that it's always the same
		// object returned from all the Lookups. You could carefully
		// track its lifetime between Lookup&Forget, and have the
		// ticking & invalidation happen only when active, but let's
		// keep this example simple.
		clockFile: &File{
			fuse: srv,
		},
	}
	filesys.clockFile.tick()
	// This goroutine never exits. That's fine for this example.
	go filesys.clockFile.update()
	if err := srv.Serve(filesys); 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)
	}
}
Пример #2
0
// Mounted mounts the fuse.Server at a temporary directory.
//
// It also waits until the filesystem is known to be visible (OS X
// workaround).
//
// After successful return, caller must clean up by calling Close.
func Mounted(filesys fs.FS, conf *fs.Config, options ...fuse.MountOption) (*Mount, error) {
	dir, err := ioutil.TempDir("", "fusetest")
	if err != nil {
		return nil, err
	}
	c, err := fuse.Mount(dir, options...)
	if err != nil {
		return nil, err
	}
	server := fs.New(c, conf)
	done := make(chan struct{})
	serveErr := make(chan error, 1)
	mnt := &Mount{
		Dir:    dir,
		Conn:   c,
		Server: server,
		Error:  serveErr,
		done:   done,
	}
	go func() {
		defer close(done)
		serveErr <- server.Serve(filesys)
	}()

	select {
	case <-mnt.Conn.Ready:
		if err := mnt.Conn.MountError; err != nil {
			return nil, err
		}
		return mnt, nil
	case err = <-mnt.Error:
		// Serve quit early
		if err != nil {
			return nil, err
		}
		return nil, errors.New("Serve exited early")
	}
}
Пример #3
0
// Attempt to mount a file system on the given directory, using the supplied
// Server to serve connection requests. This function blocks until the file
// system is successfully mounted.
func Mount(
	dir string,
	server Server,
	config *MountConfig) (mfs *MountedFileSystem, err error) {
	// Arrange for a non-nil debug logger.
	debugLogger := config.DebugLogger
	if debugLogger == nil {
		debugLogger = log.New(ioutil.Discard, "", 0)
	}

	// Initialize the struct.
	mfs = &MountedFileSystem{
		dir:                 dir,
		joinStatusAvailable: make(chan struct{}),
	}

	// Open a bazilfuse connection.
	debugLogger.Println("Opening a bazilfuse connection.")
	bfConn, err := bazilfuse.Mount(mfs.dir, config.bazilfuseOptions()...)
	if err != nil {
		err = fmt.Errorf("bazilfuse.Mount: %v", err)
		return
	}

	// Choose a parent context for ops.
	opContext := config.OpContext
	if opContext == nil {
		opContext = context.Background()
	}

	// Create a /dev/null error logger if necessary.
	errorLogger := config.ErrorLogger
	if errorLogger == nil {
		errorLogger = log.New(ioutil.Discard, "", 0)
	}

	// Create our own Connection object wrapping it.
	connection, err := newConnection(
		opContext,
		debugLogger,
		errorLogger,
		bfConn)

	if err != nil {
		bfConn.Close()
		err = fmt.Errorf("newConnection: %v", err)
		return
	}

	// Serve the connection in the background. When done, set the join status.
	go func() {
		server.ServeOps(connection)
		mfs.joinStatus = connection.close()
		close(mfs.joinStatusAvailable)
	}()

	// Wait for the connection to say it is ready.
	if err = connection.waitForReady(); err != nil {
		err = fmt.Errorf("WaitForReady: %v", err)
		return
	}

	return
}