func mountServer(token, mountpoint string) (*fuse.Server, error) {
	if err := os.MkdirAll(filepath.Dir(mountpoint), 0755); err != nil {
		return nil, err
	}

	client, err := vault.Client(token)
	if err != nil {
		return nil, err
	}

	kwfs, root := fs.NewFs(client)

	mountOptions := &fuse.MountOptions{
		AllowOther: true,
		Name:       kwfs.String(),
		Options:    []string{"default_permissions"},
	}

	// Empty Options struct avoids setting a global uid/gid override.
	conn := nodefs.NewFileSystemConnector(root, &nodefs.Options{})
	server, err := fuse.NewServer(conn.RawFS(), mountpoint, mountOptions)
	if err != nil {
		log.Printf("Mount fail: %v\n", err)
		return nil, err
	}

	go server.Serve()

	return server, nil
}
Exemple #2
0
// this function was borrowed from https://raw.githubusercontent.com/hanwen/go-fuse/master/example/memfs/main.go
func main() {
	// Scans the arg list and sets up flags
	debug := flag.Bool("debug", false, "print debugging messages.")
	flag.Parse()
	if flag.NArg() < 3 {
		fmt.Println("usage: appendfs <mountpoint> <datafile> <metadatafile>")
		os.Exit(2)
	}

	mountPoint := flag.Arg(0)
	fs, err := appendfs.NewAppendFS(flag.Arg(1), flag.Arg(2))
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}
	options := nodefs.NewOptions()
	options.Owner = nil
	conn := nodefs.NewFileSystemConnector(fs.Root(), options)
	server, err := fuse.NewServer(conn.RawFS(), mountPoint, nil)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}
	server.SetDebug(*debug)
	fmt.Println("Mounted!")
	server.Serve()
	fmt.Println("Closing filesystem")
	err = fs.Close()
	if err != nil {
		fmt.Printf("Unmount fail: %v\n", err)
		os.Exit(1)
	}
}
Exemple #3
0
func newFuseFS(tmpDir string, rpcFS *RpcFs, writableRoot string) (*fuseFS, error) {
	tmpDir, err := ioutil.TempDir(tmpDir, "termite-task")
	if err != nil {
		return nil, err
	}

	fs := &fuseFS{
		writableRoot: strings.TrimLeft(writableRoot, "/"),
		workers:      map[string]*workerFS{},
		rpcFS:        rpcFS,
		rpcNodeFS: pathfs.NewPathNodeFs(&multiRPCFS{rpcFS},
			&pathfs.PathNodeFsOptions{ClientInodes: true}),
		tmpDir: tmpDir,
		mount:  filepath.Join(tmpDir, "mnt"),
	}
	if err := os.Mkdir(fs.mount, 0755); err != nil {
		return nil, err
	}

	fs.fsConnector = nodefs.NewFileSystemConnector(fs.rpcNodeFS.Root(),
		nodeFSOptions())
	fuseOpts := fuse.MountOptions{}
	if os.Geteuid() == 0 {
		fuseOpts.AllowOther = true
	}

	fs.server, err = fuse.NewServer(fs.fsConnector.RawFS(), fs.mount, &fuseOpts)
	if err != nil {
		return nil, err
	}
	go fs.server.Serve()
	return fs, nil
}
Exemple #4
0
func main() {
	if len(os.Args) < 2 {
		fmt.Fprintf(os.Stderr, "Usage: %s <mountpoint>\n", os.Args[0])
		os.Exit(1)
	}

	mountOptions := &fuse.MountOptions{
		AllowOther: true,
		Name:       "boardfs",
		Options:    []string{"default_permissions"},
	}
	mountpoint := os.Args[1]

	root := boardfs.NewRootNode()
	conn := nodefs.NewFileSystemConnector(root, &nodefs.Options{})

	server, err := fuse.NewServer(conn.RawFS(), mountpoint, mountOptions)
	if err != nil {
		log.Fatalf("Mount fail: %v\n", err)
	}

	// shutdown fuseserver on SIGINT
	sigchan := make(chan os.Signal, 1)
	signal.Notify(sigchan, os.Interrupt, os.Kill)
	go func() {
		sig := <-sigchan
		fmt.Print("\nExiting on ", sig, "\n")
		server.Unmount()
	}()
	server.Serve()
	signal.Stop(sigchan)
}
Exemple #5
0
func pathfsFrontend(key []byte, cipherdir string, mountpoint string, debug bool, openssl bool) *fuse.Server {

	finalFs := pathfs_frontend.NewFS(key, cipherdir, openssl)
	pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
	pathFs := pathfs.NewPathNodeFs(finalFs, pathFsOpts)
	fuseOpts := &nodefs.Options{
		// These options are to be compatible with libfuse defaults,
		// making benchmarking easier.
		NegativeTimeout: time.Second,
		AttrTimeout:     time.Second,
		EntryTimeout:    time.Second,
	}
	conn := nodefs.NewFileSystemConnector(pathFs.Root(), fuseOpts)
	var mOpts fuse.MountOptions
	mOpts.AllowOther = false
	// Set values shown in "df -T" and friends
	// First column, "Filesystem"
	mOpts.Options = append(mOpts.Options, "fsname="+cipherdir)
	// Second column, "Type", will be shown as "fuse." + Name
	mOpts.Name = "gocryptfs"

	srv, err := fuse.NewServer(conn.RawFS(), mountpoint, &mOpts)
	if err != nil {
		fmt.Printf("Mount failed: %v", err)
		os.Exit(ERREXIT_MOUNT)
	}
	srv.SetDebug(debug)

	return srv
}
Exemple #6
0
// Start takes a path to the directory where the goinfo file system
// should be mounted. If the directory does not exist, it will be
// created. Start will return an error if the directory cannot be
// created or if the file system cannot be mounted at this location
// for any reason.
func Start(mountpoint string) error {
	//already mounted there
	if _, found := servers[mountpoint]; found {
		return nil
	}

	if _, err := os.Stat(mountpoint); os.IsNotExist(err) {
		if err = os.Mkdir(mountpoint, 0755); err != nil {
			return err
		}
	}

	nfs := pathfs.NewPathNodeFs(gfs, nil)
	conn := nodefs.NewFileSystemConnector(nfs.Root(), nil)
	server, err := fuse.NewServer(conn.RawFS(), mountpoint, &fuse.MountOptions{AllowOther: true})
	if err != nil {
		return errors.New("Failed to mount monitoring fs at " + mountpoint + ": " + err.Error())
	}

	servers[mountpoint] = server

	//start handling the fs calls
	go server.Serve()

	return nil
}
Exemple #7
0
func (d *driver) mountServer(mountpoint string) (*fuse.Server, error) {
	if err := os.MkdirAll(filepath.Dir(mountpoint), 0755); err != nil {
		return nil, err
	}

	conf := api.DefaultConfig()
	client, err := api.NewClient(conf)
	if err != nil {
		return nil, err
	}

	ownership := keywhizfs.NewOwnership("root", "root")
	kwfs, root := NewFs(client, ownership)

	mountOptions := &fuse.MountOptions{
		AllowOther: true,
		Name:       kwfs.String(),
		Options:    []string{"default_permissions"},
	}

	// Empty Options struct avoids setting a global uid/gid override.
	conn := nodefs.NewFileSystemConnector(root, &nodefs.Options{})
	server, err := fuse.NewServer(conn.RawFS(), mountpoint, mountOptions)
	if err != nil {
		log.Printf("Mount fail: %v\n", err)
		return nil, err
	}

	go server.Serve()

	return server, nil
}
func mount() error {
	var err error

	if fs != nil || server != nil {
		// already mounting
		return nil
	}

	// create mountpoint
	os.Mkdir(TEST_MOUNTPOINT, 0777)

	// config
	config := &config.Config{
		MountPoint:      TEST_MOUNTPOINT,
		ContainerName:   TEST_CONTAINER_NAME,
		CreateContainer: true,
		Debug:           true,
		NoDaemon:        true,
	}

	// swift
	swift := openstack.NewSwift(config)
	if err = swift.Auth(); err != nil {
		return err
	}
	swift.DeleteContainer()

	// mapper
	mapper, err := mapper.NewObjectMapper(config)
	if err != nil {
		return err
	}

	// initialize filesystem
	fs = NewObjectFileSystem(config, mapper)

	path := pathfs.NewPathNodeFs(fs, nil)
	con := nodefs.NewFileSystemConnector(path.Root(), &nodefs.Options{})

	opts := &fuse.MountOptions{
		Name:   "test-filesystem",
		FsName: "test-filesystem",
	}

	// create server and do mount with dedicated goroutine
	server, err = fuse.NewServer(con.RawFS(), TEST_MOUNTPOINT, opts)
	if err != nil {
		return err
	}

	go func() {
		server.Serve()
	}()

	server.WaitMount()

	return nil
}
Exemple #9
0
func main() {
	var Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [options] url mountpoint\n", os.Args[0])
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() != 2 {
		Usage()
		os.Exit(1)
	}

	serverURL, mountpoint := flag.Args()[0], flag.Args()[1]

	logConfig := klog.Config{*debug, mountpoint}
	logger = klog.New("kwfs_main", logConfig)
	defer logger.Close()

	if *certFile == "" {
		logger.Debugf("Certificate file not specified, assuming certificate also in %s", *keyFile)
		certFile = keyFile
	}

	lockMemory()

	clientTimeout := time.Duration(*timeoutSeconds) * time.Second
	freshThreshold := 200 * time.Millisecond
	backendDeadline := 500 * time.Millisecond
	maxWait := clientTimeout + backendDeadline
	timeouts := keywhizfs.Timeouts{freshThreshold, backendDeadline, maxWait}

	client := keywhizfs.NewClient(*certFile, *keyFile, *caFile, serverURL, clientTimeout, logConfig, *ping)

	ownership := keywhizfs.NewOwnership(*user, *group)
	kwfs, root, err := keywhizfs.NewKeywhizFs(&client, ownership, timeouts, logConfig)
	if err != nil {
		log.Fatalf("KeywhizFs init fail: %v\n", err)
	}

	mountOptions := &fuse.MountOptions{
		AllowOther: true,
		Name:       kwfs.String(),
		Options:    []string{"default_permissions"},
	}

	// Empty Options struct avoids setting a global uid/gid override.
	conn := nodefs.NewFileSystemConnector(root, &nodefs.Options{})
	server, err := fuse.NewServer(conn.RawFS(), mountpoint, mountOptions)
	if err != nil {
		log.Fatalf("Mount fail: %v\n", err)
	}

	server.Serve()
}
Exemple #10
0
// Create and mount filesystem.
func NewTestCase(t *testing.T) *testCase {
	tc := &testCase{}
	tc.tester = t

	// Make sure system setting does not affect test.
	syscall.Umask(0)

	const name string = "hello.txt"
	const subdir string = "subdir"

	var err error
	tc.tmpDir, err = ioutil.TempDir("", "go-fuse")
	if err != nil {
		t.Fatalf("TempDir failed: %v", err)
	}
	tc.orig = tc.tmpDir + "/orig"
	tc.mnt = tc.tmpDir + "/mnt"

	tc.Mkdir(tc.orig, 0700)
	tc.Mkdir(tc.mnt, 0700)

	tc.mountFile = filepath.Join(tc.mnt, name)
	tc.mountSubdir = filepath.Join(tc.mnt, subdir)
	tc.origFile = filepath.Join(tc.orig, name)
	tc.origSubdir = filepath.Join(tc.orig, subdir)

	var pfs pathfs.FileSystem
	pfs = pathfs.NewLoopbackFileSystem(tc.orig)
	pfs = pathfs.NewLockingFileSystem(pfs)

	tc.pathFs = pathfs.NewPathNodeFs(pfs, &pathfs.PathNodeFsOptions{
		ClientInodes: true})
	tc.connector = nodefs.NewFileSystemConnector(tc.pathFs.Root(),
		&nodefs.Options{
			EntryTimeout:    testTtl,
			AttrTimeout:     testTtl,
			NegativeTimeout: 0.0,
			Debug:           VerboseTest(),
		})
	tc.state, err = fuse.NewServer(
		fuse.NewRawFileSystem(tc.connector.RawFS()), tc.mnt, &fuse.MountOptions{
			SingleThreaded: true,
			Debug:          VerboseTest(),
		})
	if err != nil {
		t.Fatal("NewServer:", err)
	}

	go tc.state.Serve()
	if err := tc.state.WaitMount(); err != nil {
		t.Fatal("WaitMount", err)
	}
	return tc
}
Exemple #11
0
// Create and mount filesystem.
func NewTestCase(t *testing.T) *testCase {
	me := &testCase{}
	me.tester = t

	// Make sure system setting does not affect test.
	syscall.Umask(0)

	const name string = "hello.txt"
	const subdir string = "subdir"

	var err error
	me.tmpDir, err = ioutil.TempDir("", "go-fuse")
	if err != nil {
		t.Fatalf("TempDir failed: %v", err)
	}
	me.orig = me.tmpDir + "/orig"
	me.mnt = me.tmpDir + "/mnt"

	os.Mkdir(me.orig, 0700)
	os.Mkdir(me.mnt, 0700)

	me.mountFile = filepath.Join(me.mnt, name)
	me.mountSubdir = filepath.Join(me.mnt, subdir)
	me.origFile = filepath.Join(me.orig, name)
	me.origSubdir = filepath.Join(me.orig, subdir)

	var pfs pathfs.FileSystem
	pfs = pathfs.NewLoopbackFileSystem(me.orig)
	pfs = pathfs.NewLockingFileSystem(pfs)

	me.pathFs = pathfs.NewPathNodeFs(pfs, &pathfs.PathNodeFsOptions{
		ClientInodes: true})
	me.connector = nodefs.NewFileSystemConnector(me.pathFs.Root(),
		&nodefs.Options{
			EntryTimeout:    testTtl,
			AttrTimeout:     testTtl,
			NegativeTimeout: 0.0,
		})
	me.connector.SetDebug(VerboseTest())
	me.state, err = fuse.NewServer(
		fuse.NewRawFileSystem(me.connector.RawFS()), me.mnt, &fuse.MountOptions{SingleThreaded: true})
	if err != nil {
		t.Fatal("NewServer:", err)
	}

	me.state.SetDebug(VerboseTest())

	// Unthreaded, but in background.
	go me.state.Serve()

	me.state.WaitMount()
	return me
}
Exemple #12
0
func main() {
	fsdebug := flag.Bool("fs-debug", false, "switch on FS debugging")
	p4port := flag.String("p4-server", "", "address for P4 server")
	p4binary := flag.String("p4-binary", "p4", "binary for P4 commandline client")
	backingDir := flag.String("backing", "", "directory to store file contents.")
	profile := flag.String("profile", "", "record cpu profile.")
	flag.Parse()

	if len(flag.Args()) != 1 {
		log.Fatal("Usage: p4fs MOUNT-POINT")
	}
	mountpoint := flag.Arg(0)

	opts := p4.ConnOptions{
		Binary:  *p4binary,
		Address: *p4port,
	}
	p4conn := p4.NewConn(opts)

	if *backingDir == "" {
		d, err := ioutil.TempDir("", "p4fs")
		if err != nil {
			log.Fatalf("TempDir failed: %v", err)
		}
		*backingDir = d
		defer os.RemoveAll(d)
	}

	root := NewP4FSRoot(p4conn, *backingDir)
	conn := nodefs.NewFileSystemConnector(root, nodefs.NewOptions())

	mount, err := fuse.NewServer(conn.RawFS(), mountpoint, nil)
	if err != nil {
		log.Fatalf("mount failed: %v", err)
	}

	conn.SetDebug(*fsdebug)
	mount.SetDebug(*fsdebug)
	log.Println("starting FUSE.")

	if *profile != "" {
		profFile, err := os.Create(*profile)
		if err != nil {
			log.Fatalf("os.Create: %v", err)
		}
		pprof.StartCPUProfile(profFile)
		defer pprof.StopCPUProfile()
	}

	mount.Serve()
}
func (d *keywhizDriver) mountServer(mountpoint string) (*fuse.Server, error) {
	logConfig := klog.Config{
		Debug:      d.config.Debug,
		Mountpoint: mountpoint,
	}

	if err := os.MkdirAll(filepath.Dir(mountpoint), 0755); err != nil {
		return nil, err
	}

	freshThreshold := 200 * time.Millisecond
	backendDeadline := 500 * time.Millisecond
	maxWait := d.config.TimeoutSeconds + backendDeadline
	timeouts := keywhizfs.Timeouts{
		Fresh:           freshThreshold,
		BackendDeadline: backendDeadline,
		MaxWait:         maxWait,
	}

	client := keywhizfs.NewClient(d.config.CertFile, d.config.KeyFile, d.config.CaFile,
		d.config.ServerURL, d.config.TimeoutSeconds, logConfig, d.config.Ping)

	ownership := keywhizfs.NewOwnership(d.config.User, d.config.Group)
	kwfs, root, err := keywhizfs.NewKeywhizFs(&client, ownership, timeouts, logConfig)
	if err != nil {
		client.Errorf("Mount fail: %v\n", err)
		return nil, err
	}

	mountOptions := &fuse.MountOptions{
		AllowOther: true,
		Name:       kwfs.String(),
		Options:    []string{"default_permissions"},
	}

	// Empty Options struct avoids setting a global uid/gid override.
	conn := nodefs.NewFileSystemConnector(root, &nodefs.Options{})
	server, err := fuse.NewServer(conn.RawFS(), mountpoint, mountOptions)
	if err != nil {
		client.Errorf("Mount fail: %v\n", err)
		return nil, err
	}

	go server.Serve()

	return server, nil
}
Exemple #14
0
func MountVfs(store *storage.Storage, mountPath string, options []string) (*FuseVfs, error) {
	fuseVfs := FuseVfs{nil, "", nil}

	pathFs := pathfs.NewPathNodeFs(&fuseVfs, nil)
	conn := nodefs.NewFileSystemConnector(pathFs.Root(), nil)
	mountOptions := &fuse.MountOptions{Options: options}

	server, err := fuse.NewServer(conn.RawFS(), mountPath, mountOptions)
	if err != nil {
		return nil, fmt.Errorf("could not mount virtual filesystem at '%v': %v", mountPath, err)
	}

	fuseVfs.store = store
	fuseVfs.mountPath = mountPath
	fuseVfs.server = server

	return &fuseVfs, nil
}
Exemple #15
0
func main() {
	// Scans the arg list and sets up flags
	debug := flag.Bool("debug", false, "print debugging messages.")
	other := flag.Bool("allow-other", false, "mount with -o allowother.")
	flag.Parse()
	if flag.NArg() < 2 {
		// TODO - where to get program name?
		fmt.Println("usage: main MOUNTPOINT ORIGINAL")
		os.Exit(2)
	}

	var finalFs pathfs.FileSystem
	orig := flag.Arg(1)
	loopbackfs := pathfs.NewLoopbackFileSystem(orig)
	finalFs = loopbackfs

	opts := &nodefs.Options{
		// These options are to be compatible with libfuse defaults,
		// making benchmarking easier.
		NegativeTimeout: time.Second,
		AttrTimeout:     time.Second,
		EntryTimeout:    time.Second,
	}
	pathFs := pathfs.NewPathNodeFs(finalFs, nil)
	conn := nodefs.NewFileSystemConnector(pathFs.Root(), opts)
	mountPoint := flag.Arg(0)
	origAbs, _ := filepath.Abs(orig)
	mOpts := &fuse.MountOptions{
		AllowOther: *other,
		Name:       "loopbackfs",
		FsName:     origAbs,
	}
	state, err := fuse.NewServer(conn.RawFS(), mountPoint, mOpts)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}
	state.SetDebug(*debug)

	fmt.Println("Mounted!")
	state.Serve()
}
Exemple #16
0
func mount(fs pathfs.FileSystem, mountpoint string) (server *fuse.Server, err error) {
	path := pathfs.NewPathNodeFs(fs, nil)
	con := nodefs.NewFileSystemConnector(path.Root(), &nodefs.Options{
		EntryTimeout:    time.Second,
		AttrTimeout:     time.Second,
		NegativeTimeout: time.Second,
	})

	opts := &fuse.MountOptions{
		Name:   config.APP_NAME,
		FsName: config.APP_NAME,
	}

	server, err = fuse.NewServer(con.RawFS(), mountpoint, opts)
	if err != nil {
		return nil, err
	}

	return server, nil
}
Exemple #17
0
// this function was borrowed from https://raw.githubusercontent.com/hanwen/go-fuse/master/example/memfs/main.go
func main() {
	// Scans the arg list and sets up flags
	debug := flag.Bool("debug", false, "print debugging messages.")
	flag.Parse()
	if flag.NArg() < 1 {
		fmt.Println("usage: inmemfs MOUNTPOINT")
		os.Exit(2)
	}

	mountPoint := flag.Arg(0)
	root := newInMemFS().root
	conn := nodefs.NewFileSystemConnector(root, nil)
	server, err := fuse.NewServer(conn.RawFS(), mountPoint, nil)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}
	server.SetDebug(*debug)
	fmt.Println("Mounted!")
	server.Serve()
}
Exemple #18
0
func main() {

	var finalFs pathfs.FileSystem

	config, err := parseConfig("config.json")
	if err != nil {
		log.Fatal(err)
	}

	event.StartListening()

	kakigoorifs := fs.NewKakigooriFileSystem(config.Root)
	finalFs = kakigoorifs

	opts := &nodefs.Options{
		NegativeTimeout: time.Second,
		AttrTimeout:     time.Second,
		EntryTimeout:    time.Second,
	}

	pathFs := pathfs.NewPathNodeFs(finalFs, nil)
	conn := nodefs.NewFileSystemConnector(pathFs, opts)

	mOpts := &fuse.MountOptions{
		AllowOther: false,
	}
	state, err := fuse.NewServer(conn.RawFS(), config.MountPoint, mOpts)
	if err != nil {
		log.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	state.SetDebug(false)

	log.Println("Mounted!")
	state.Serve()

}
Exemple #19
0
func main() {
	// Scans the arg list and sets up flags
	debug := flag.Bool("debug", false, "print debugging messages.")
	flag.Parse()
	if flag.NArg() < 2 {
		// TODO - where to get program name?
		fmt.Println("usage: main MOUNTPOINT BACKING-PREFIX")
		os.Exit(2)
	}

	mountPoint := flag.Arg(0)
	prefix := flag.Arg(1)
	fs := nodefs.NewMemNodeFs(prefix)
	conn := nodefs.NewFileSystemConnector(fs, nil)
	server, err := fuse.NewServer(conn.RawFS(), mountPoint, nil)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}
	server.SetDebug(*debug)
	fmt.Println("Mounted!")
	server.Serve()
}
Exemple #20
0
func mountAndServe(options *Options) {
	log.Printf("[DEBUG] mounting at %s directed at %s with options: %+v", options.Args.Mountpoint, options.Endpoint, options.MountOptions.opts)
	nfs := pathfs.NewPathNodeFs(metadatafs.New(options.Endpoint), nil)
	server, err := fuse.NewServer(
		nodefs.NewFileSystemConnector(nfs.Root(), nil).RawFS(),
		options.Args.Mountpoint,
		&fuse.MountOptions{Options: options.MountOptions.opts})
	if err != nil {
		log.Fatalf("mount fail: %v\n", err)
	}

	server.SetDebug(len(options.Verbose) >= moreVerbose)

	if options.Tags {
		go func() {
			server.WaitMount()
			log.Printf("[DEBUG] mounting tags")
			mountTags(nfs, options)
			log.Printf("[DEBUG] tags mounted")
		}()
	}
	log.Printf("[DEBUG] mounting")
	server.Serve()
}
Exemple #21
0
// pathfsFrontend - initialize gocryptfs/pathfs_frontend
// Calls os.Exit on errors
func pathfsFrontend(key []byte, args argContainer, confFile *cryptfs.ConfFile) *fuse.Server {

	// Reconciliate CLI and config file arguments into a Args struct that is passed to the
	// filesystem implementation
	frontendArgs := pathfs_frontend.Args{
		Cipherdir:      args.cipherdir,
		Masterkey:      key,
		OpenSSL:        args.openssl,
		PlaintextNames: args.plaintextnames,
		DirIV:          args.diriv,
		EMENames:       args.emenames,
		GCMIV128:       args.gcmiv128,
	}
	// confFile is nil when "-zerokey" or "-masterkey" was used
	if confFile != nil {
		// Settings from the config file override command line args
		frontendArgs.PlaintextNames = confFile.IsFeatureFlagSet(cryptfs.FlagPlaintextNames)
		frontendArgs.DirIV = confFile.IsFeatureFlagSet(cryptfs.FlagDirIV)
		frontendArgs.EMENames = confFile.IsFeatureFlagSet(cryptfs.FlagEMENames)
		frontendArgs.GCMIV128 = confFile.IsFeatureFlagSet(cryptfs.FlagGCMIV128)
	}
	// EMENames implies DirIV, both on the command line and in the config file.
	if frontendArgs.EMENames {
		frontendArgs.DirIV = true
	}
	// PlainTexnames disables both EMENames and DirIV
	if frontendArgs.PlaintextNames {
		frontendArgs.DirIV = false
		frontendArgs.EMENames = false
	}
	cryptfs.Debug.Printf("frontendArgs: ")
	cryptfs.Debug.JSONDump(frontendArgs)

	finalFs := pathfs_frontend.NewFS(frontendArgs)
	pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
	pathFs := pathfs.NewPathNodeFs(finalFs, pathFsOpts)
	fuseOpts := &nodefs.Options{
		// These options are to be compatible with libfuse defaults,
		// making benchmarking easier.
		NegativeTimeout: time.Second,
		AttrTimeout:     time.Second,
		EntryTimeout:    time.Second,
	}
	conn := nodefs.NewFileSystemConnector(pathFs.Root(), fuseOpts)
	var mOpts fuse.MountOptions
	mOpts.AllowOther = false
	// Set values shown in "df -T" and friends
	// First column, "Filesystem"
	mOpts.Options = append(mOpts.Options, "fsname="+args.cipherdir)
	// Second column, "Type", will be shown as "fuse." + Name
	mOpts.Name = "gocryptfs"

	srv, err := fuse.NewServer(conn.RawFS(), args.mountpoint, &mOpts)
	if err != nil {
		fmt.Printf("Mount failed: %v", err)
		os.Exit(ERREXIT_MOUNT)
	}
	srv.SetDebug(args.fusedebug)

	// All FUSE file and directory create calls carry explicit permission
	// information. We need an unrestricted umask to create the files and
	// directories with the requested permissions.
	syscall.Umask(0000)

	return srv
}
Exemple #22
0
func main() {
	// Scans the arg list and sets up flags
	debug := flag.Bool("debug", false, "print debugging messages.")
	other := flag.Bool("allow-other", false, "mount with -o allowother.")
	cpuprofile := flag.String("cpuprofile", "", "write cpu profile to this file")
	memprofile := flag.String("memprofile", "", "write memory profile to this file")
	flag.Parse()
	if flag.NArg() < 2 {
		fmt.Printf("usage: %s MOUNTPOINT ORIGINAL\n", path.Base(os.Args[0]))
		os.Exit(2)
	}
	if *cpuprofile != "" {
		fmt.Printf("Writing cpu profile to %s\n", *cpuprofile)
		f, err := os.Create(*cpuprofile)
		if err != nil {
			fmt.Println(err)
			os.Exit(3)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}
	if *memprofile != "" {
		fmt.Printf("Writing mem profile to %s\n", *memprofile)
		f, err := os.Create(*memprofile)
		if err != nil {
			fmt.Println(err)
			os.Exit(4)
		}
		defer func() {
			pprof.WriteHeapProfile(f)
			f.Close()
			return
		}()
	}
	if *cpuprofile != "" || *memprofile != "" {
		fmt.Printf("Note: You must unmount gracefully, otherwise the profile file(s) will stay empty!\n")
	}

	var finalFs pathfs.FileSystem
	orig := flag.Arg(1)
	loopbackfs := pathfs.NewLoopbackFileSystem(orig)
	finalFs = loopbackfs

	opts := &nodefs.Options{
		// These options are to be compatible with libfuse defaults,
		// making benchmarking easier.
		NegativeTimeout: time.Second,
		AttrTimeout:     time.Second,
		EntryTimeout:    time.Second,
	}
	pathFs := pathfs.NewPathNodeFs(finalFs, nil)
	conn := nodefs.NewFileSystemConnector(pathFs.Root(), opts)
	mountPoint := flag.Arg(0)
	origAbs, _ := filepath.Abs(orig)
	mOpts := &fuse.MountOptions{
		AllowOther: *other,
		Name:       "loopbackfs",
		FsName:     origAbs,
	}
	state, err := fuse.NewServer(conn.RawFS(), mountPoint, mOpts)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}
	state.SetDebug(*debug)

	fmt.Println("Mounted!")
	state.Serve()
}
Exemple #23
0
func main() {
	log.SetFlags(log.Lmicroseconds)
	// Scans the arg list and sets up flags
	debug := flag.Bool("debug", false, "print debugging messages.")
	other := flag.Bool("allow-other", false, "mount with -o allowother.")
	enableLinks := flag.Bool("l", false, "Enable hard link support")
	cpuprofile := flag.String("cpuprofile", "", "write cpu profile to this file")
	memprofile := flag.String("memprofile", "", "write memory profile to this file")
	flag.Parse()
	if flag.NArg() < 2 {
		fmt.Printf("usage: %s MOUNTPOINT ORIGINAL\n", path.Base(os.Args[0]))
		fmt.Printf("\noptions:\n")
		flag.PrintDefaults()
		os.Exit(2)
	}
	if *cpuprofile != "" {
		fmt.Printf("Writing cpu profile to %s\n", *cpuprofile)
		f, err := os.Create(*cpuprofile)
		if err != nil {
			fmt.Println(err)
			os.Exit(3)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}
	if *memprofile != "" {
		log.Printf("send SIGUSR1 to %d to dump memory profile", os.Getpid())
		profSig := make(chan os.Signal, 1)
		signal.Notify(profSig, syscall.SIGUSR1)
		go writeMemProfile(*memprofile, profSig)
	}
	if *cpuprofile != "" || *memprofile != "" {
		fmt.Printf("Note: You must unmount gracefully, otherwise the profile file(s) will stay empty!\n")
	}

	var finalFs pathfs.FileSystem
	orig := flag.Arg(1)
	loopbackfs := pathfs.NewLoopbackFileSystem(orig)
	finalFs = loopbackfs

	opts := &nodefs.Options{
		// These options are to be compatible with libfuse defaults,
		// making benchmarking easier.
		NegativeTimeout: time.Second,
		AttrTimeout:     time.Second,
		EntryTimeout:    time.Second,
	}
	// Enable ClientInodes so hard links work
	pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: *enableLinks}
	pathFs := pathfs.NewPathNodeFs(finalFs, pathFsOpts)
	conn := nodefs.NewFileSystemConnector(pathFs.Root(), opts)
	mountPoint := flag.Arg(0)
	origAbs, _ := filepath.Abs(orig)
	mOpts := &fuse.MountOptions{
		AllowOther: *other,
		Name:       "loopbackfs",
		FsName:     origAbs,
		Debug:      *debug,
	}
	state, err := fuse.NewServer(conn.RawFS(), mountPoint, mOpts)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("Mounted!")
	state.Serve()
}
Exemple #24
0
func main() {
	debug := flag.String("debug", "", "comma-separated list of debugging options: usb, data, mtp, fuse")
	usbTimeout := flag.Int("usb-timeout", 5000, "timeout in milliseconds")
	vfat := flag.Bool("vfat", true, "assume removable RAM media uses VFAT, and rewrite names.")
	other := flag.Bool("allow-other", false, "allow other users to access mounted fuse. Default: false.")
	deviceFilter := flag.String("dev", "",
		"regular expression to filter device IDs, "+
			"which are composed of manufacturer/product/serial.")
	storageFilter := flag.String("storage", "", "regular expression to filter storage areas.")
	android := flag.Bool("android", true, "use android extensions if available")
	flag.Parse()

	if len(flag.Args()) != 1 {
		log.Fatalf("Usage: %s [options] MOUNT-POINT\n", os.Args[0])
	}
	mountpoint := flag.Arg(0)

	dev, err := mtp.SelectDevice(*deviceFilter)
	if err != nil {
		log.Fatalf("detect failed: %v", err)
	}
	defer dev.Close()
	debugs := map[string]bool{}
	for _, s := range strings.Split(*debug, ",") {
		debugs[s] = true
	}
	dev.MTPDebug = debugs["mtp"]
	dev.DataDebug = debugs["data"]
	dev.USBDebug = debugs["usb"]
	dev.Timeout = *usbTimeout
	if err = dev.Configure(); err != nil {
		log.Fatalf("Configure failed: %v", err)
	}

	sids, err := fs.SelectStorages(dev, *storageFilter)
	if err != nil {
		log.Fatalf("selectStorages failed: %v", err)
	}

	opts := fs.DeviceFsOptions{
		RemovableVFat: *vfat,
		Android:       *android,
	}
	fs, err := fs.NewDeviceFs(dev, sids, opts)
	if err != nil {
		log.Fatalf("NewDeviceFs failed: %v", err)
	}
	conn := nodefs.NewFileSystemConnector(fs, nodefs.NewOptions())
	rawFs := fuse.NewLockingRawFileSystem(conn.RawFS())

	mOpts := &fuse.MountOptions{
		AllowOther: *other,
	}
	mount, err := fuse.NewServer(rawFs, mountpoint, mOpts)
	if err != nil {
		log.Fatalf("mount failed: %v", err)
	}

	conn.SetDebug(debugs["fuse"] || debugs["fs"])
	mount.SetDebug(debugs["fuse"] || debugs["fs"])
	log.Printf("starting FUSE.")
	mount.Serve()
	fs.OnUnmount()
}
Exemple #25
0
// initFuseFrontend - initialize gocryptfs/fusefrontend
// Calls os.Exit on errors
func initFuseFrontend(key []byte, args *argContainer, confFile *configfile.ConfFile) *fuse.Server {
	// Reconciliate CLI and config file arguments into a fusefrontend.Args struct
	// that is passed to the filesystem implementation
	cryptoBackend := cryptocore.BackendGoGCM
	if args.openssl {
		cryptoBackend = cryptocore.BackendOpenSSL
	}
	if args.aessiv {
		cryptoBackend = cryptocore.BackendAESSIV
	}
	frontendArgs := fusefrontend.Args{
		Cipherdir:      args.cipherdir,
		Masterkey:      key,
		PlaintextNames: args.plaintextnames,
		LongNames:      args.longnames,
		CryptoBackend:  cryptoBackend,
		ConfigCustom:   args._configCustom,
		Raw64:          args.raw64,
		NoPrealloc:     args.noprealloc,
	}
	// confFile is nil when "-zerokey" or "-masterkey" was used
	if confFile != nil {
		// Settings from the config file override command line args
		frontendArgs.PlaintextNames = confFile.IsFeatureFlagSet(configfile.FlagPlaintextNames)
		frontendArgs.Raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64)
		if confFile.IsFeatureFlagSet(configfile.FlagAESSIV) {
			frontendArgs.CryptoBackend = cryptocore.BackendAESSIV
		} else if args.reverse {
			tlog.Fatal.Printf("AES-SIV is required by reverse mode, but not enabled in the config file")
			os.Exit(ErrExitUsage)
		}
	}
	// If allow_other is set and we run as root, try to give newly created files to
	// the right user.
	if args.allow_other && os.Getuid() == 0 {
		frontendArgs.PreserveOwner = true
	}
	jsonBytes, _ := json.MarshalIndent(frontendArgs, "", "\t")
	tlog.Debug.Printf("frontendArgs: %s", string(jsonBytes))
	var finalFs pathfs.FileSystem
	var ctlSockBackend ctlsock.Interface
	if args.reverse {
		fs := fusefrontend_reverse.NewFS(frontendArgs)
		finalFs = fs
		ctlSockBackend = fs
	} else {
		fs := fusefrontend.NewFS(frontendArgs)
		finalFs = fs
		ctlSockBackend = fs
	}
	// We have opened the socket early so that we cannot fail here after
	// asking the user for the password
	if args._ctlsockFd != nil {
		go ctlsock.Serve(args._ctlsockFd, ctlSockBackend)
	}
	pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
	pathFs := pathfs.NewPathNodeFs(finalFs, pathFsOpts)
	fuseOpts := &nodefs.Options{
		// These options are to be compatible with libfuse defaults,
		// making benchmarking easier.
		NegativeTimeout: time.Second,
		AttrTimeout:     time.Second,
		EntryTimeout:    time.Second,
	}
	conn := nodefs.NewFileSystemConnector(pathFs.Root(), fuseOpts)
	var mOpts fuse.MountOptions
	mOpts.AllowOther = false
	if args.allow_other {
		tlog.Info.Printf(tlog.ColorYellow + "The option \"-allow_other\" is set. Make sure the file " +
			"permissions protect your data from unwanted access." + tlog.ColorReset)
		mOpts.AllowOther = true
		// Make the kernel check the file permissions for us
		mOpts.Options = append(mOpts.Options, "default_permissions")
	}
	if args.nonempty {
		mOpts.Options = append(mOpts.Options, "nonempty")
	}
	// Set values shown in "df -T" and friends
	// First column, "Filesystem"
	mOpts.Options = append(mOpts.Options, "fsname="+args.cipherdir)
	// Second column, "Type", will be shown as "fuse." + Name
	mOpts.Name = "gocryptfs"
	if args.reverse {
		mOpts.Name += "-reverse"
	}
	// The kernel enforces read-only operation, we just have to pass "ro".
	// Reverse mounts are always read-only.
	if args.ro || args.reverse {
		mOpts.Options = append(mOpts.Options, "ro")
	}
	// Add additional mount options (if any) after the stock ones, so the user has
	// a chance to override them.
	if args.ko != "" {
		parts := strings.Split(args.ko, ",")
		tlog.Debug.Printf("Adding -ko mount options: %v", parts)
		mOpts.Options = append(mOpts.Options, parts...)
	}
	srv, err := fuse.NewServer(conn.RawFS(), args.mountpoint, &mOpts)
	if err != nil {
		tlog.Fatal.Printf("Mount failed: %v", err)
		os.Exit(ErrExitMount)
	}
	srv.SetDebug(args.fusedebug)

	// All FUSE file and directory create calls carry explicit permission
	// information. We need an unrestricted umask to create the files and
	// directories with the requested permissions.
	syscall.Umask(0000)

	return srv
}
Exemple #26
0
func startFs(t *testing.T, useAndroid bool) (root string, cleanup func()) {
	dev, err := mtp.SelectDevice("")
	if err != nil {
		t.Fatalf("SelectDevice failed: %v", err)
	}
	defer func() {
		if dev != nil {
			dev.Close()
		}
	}()

	if err = dev.Configure(); err != nil {
		t.Fatalf("Configure failed: %v", err)
	}

	sids, err := SelectStorages(dev, "")
	if err != nil {
		t.Fatalf("selectStorages failed: %v", err)
	}
	if len(sids) == 0 {
		t.Fatal("no storages found. Unlock device?")
	}
	tempdir, err := ioutil.TempDir("", "mtpfs")
	if err != nil {
		t.Fatal(err)
	}
	opts := DeviceFsOptions{
		Android: useAndroid,
	}
	fs, err := NewDeviceFs(dev, sids, opts)
	if err != nil {
		t.Fatal("NewDeviceFs failed:", err)
	}
	conn := nodefs.NewFileSystemConnector(fs, nodefs.NewOptions())
	rawFs := fuse.NewLockingRawFileSystem(conn.RawFS())
	mount, err := fuse.NewServer(rawFs, tempdir, nil)
	if err != nil {
		t.Fatalf("mount failed: %v", err)
	}

	mount.SetDebug(fuse.VerboseTest())
	dev.MTPDebug = fuse.VerboseTest()
	dev.USBDebug = fuse.VerboseTest()
	dev.DataDebug = fuse.VerboseTest()
	go mount.Serve()

	for i := 0; i < 10; i++ {
		fis, err := ioutil.ReadDir(tempdir)
		if err == nil && len(fis) > 0 {
			root = filepath.Join(tempdir, fis[0].Name())
			break
		}
		time.Sleep(1)
	}

	if root == "" {
		mount.Unmount()
		t.Fatal("could not find entries in mount point.")
	}

	d := dev
	dev = nil
	return root, func() {
		mount.Unmount()
		d.Close()
	}
}
func TestDeleteNotify(t *testing.T) {
	dir := testutil.TempDir()
	defer os.RemoveAll(dir)
	root := nodefs.NewMemNodeFSRoot(dir + "/backing")
	conn := nodefs.NewFileSystemConnector(root,
		&nodefs.Options{PortableInodes: true})
	mnt := dir + "/mnt"
	err := os.Mkdir(mnt, 0755)
	if err != nil {
		t.Fatal(err)
	}

	state, err := fuse.NewServer(conn.RawFS(), mnt, &fuse.MountOptions{
		Debug: testutil.VerboseTest(),
	})
	if err != nil {
		t.Fatal(err)
	}
	go state.Serve()
	defer state.Unmount()
	if err := state.WaitMount(); err != nil {
		t.Fatal("WaitMount", err)
	}

	_, code := root.Mkdir("testdir", 0755, nil)
	if !code.Ok() {
		t.Fatal(code)
	}

	ch := root.Inode().RmChild("testdir")
	ch.Node().SetInode(nil)
	flip := flipNode{
		Node: ch.Node(),
		ok:   make(chan int),
	}
	root.Inode().NewChild("testdir", true, &flip)

	err = ioutil.WriteFile(mnt+"/testdir/testfile", []byte{42}, 0644)
	if err != nil {
		t.Fatal(err)
	}

	// Do the test here, so we surely have state.KernelSettings()
	if state.KernelSettings().Minor < 18 {
		t.Log("Kernel does not support deletion notify; aborting test.")
		return
	}
	buf := bytes.Buffer{}
	cmd := exec.Command("/usr/bin/tail", "-f", "testfile")
	cmd.Dir = mnt + "/testdir"
	cmd.Stdin = &buf
	cmd.Stdout = &bytes.Buffer{}
	cmd.Stderr = os.Stderr
	err = cmd.Start()
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		cmd.Process.Kill()
		time.Sleep(100 * time.Millisecond)
	}()

	// Wait until tail opened the file.
	time.Sleep(100 * time.Millisecond)
	err = os.Remove(mnt + "/testdir/testfile")
	if err != nil {
		t.Fatal(err)
	}

	// Simulate deletion+mkdir coming from the network
	close(flip.ok)
	oldCh := root.Inode().RmChild("testdir")
	_, code = root.Inode().Node().Mkdir("testdir", 0755, nil)
	if !code.Ok() {
		t.Fatal("mkdir status", code)
	}
	conn.DeleteNotify(root.Inode(), oldCh, "testdir")

	_, err = os.Lstat(mnt + "/testdir")
	if err != nil {
		t.Fatalf("lstat after del + mkdir failed: %v", err)
	}
}