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 }
// 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) } }
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 }
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) }
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 }
// 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 }
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 }
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() }
// 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 }
// 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 }
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 }
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 }
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() }
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 }
// 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() }
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() }
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() }
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() }
// 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 }
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() }
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() }
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() }
// 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 }
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) } }