func TestNonexistentMountPoint(t *testing.T) { ctx := context.Background() // Set up a temporary directory. dir, err := ioutil.TempDir("", "mount_test") if err != nil { t.Fatal("ioutil.TempDir: %v", err) } defer os.RemoveAll(dir) // Attempt to mount into a sub-directory that doesn't exist. fs := &minimalFS{} mfs, err := fuse.Mount( path.Join(dir, "foo"), fuseutil.NewFileSystemServer(fs), &fuse.MountConfig{}) if err == nil { fuse.Unmount(mfs.Dir()) mfs.Join(ctx) t.Fatal("fuse.Mount returned nil") } const want = "no such file" if got := err.Error(); !strings.Contains(got, want) { t.Errorf("Unexpected error: %v", got) } }
func TestSuccessfulMount(t *testing.T) { ctx := context.Background() // Set up a temporary directory. dir, err := ioutil.TempDir("", "mount_test") if err != nil { t.Fatal("ioutil.TempDir: %v", err) } defer os.RemoveAll(dir) // Mount. fs := &minimalFS{} mfs, err := fuse.Mount( dir, fuseutil.NewFileSystemServer(fs), &fuse.MountConfig{}) if err != nil { t.Fatalf("fuse.Mount: %v", err) } defer func() { if err := mfs.Join(ctx); err != nil { t.Errorf("Joining: %v", err) } }() defer fuse.Unmount(mfs.Dir()) }
// Mount the file system based on the supplied arguments, returning a // fuse.MountedFileSystem that can be joined to wait for unmounting. func mount( ctx context.Context, bucketName string, mountPoint string, flags *FlagStorage) (mfs *fuse.MountedFileSystem, err error) { // Choose UID and GID. uid, gid, err := MyUserAndGroup() if err != nil { err = fmt.Errorf("MyUserAndGroup: %v", err) return } if int32(flags.Uid) == -1 { flags.Uid = uid } if int32(flags.Gid) == -1 { flags.Gid = gid } awsConfig := &aws.Config{ Region: aws.String("us-west-2"), //LogLevel: aws.LogLevel(aws.LogDebug), } if len(flags.Endpoint) > 0 { awsConfig.Endpoint = &flags.Endpoint } if flags.UsePathRequest { awsConfig.S3ForcePathStyle = aws.Bool(true) } goofys := NewGoofys(bucketName, awsConfig, flags) if goofys == nil { err = fmt.Errorf("Mount: initialization failed") return } server := fuseutil.NewFileSystemServer(goofys) // Mount the file system. mountCfg := &fuse.MountConfig{ FSName: bucketName, Options: flags.MountOptions, ErrorLogger: log.New(os.Stderr, "fuse: ", log.Flags()), DisableWritebackCaching: true, } if flags.DebugFuse { mountCfg.DebugLogger = log.New(os.Stderr, "fuse_debug: ", 0) } mfs, err = fuse.Mount(mountPoint, server, mountCfg) if err != nil { err = fmt.Errorf("Mount: %v", err) return } return }
// Create a file system with a fixed structure that looks like this: // // hello // dir/ // world // // Each file contains the string "Hello, world!". func NewHelloFS(clock timeutil.Clock) (server fuse.Server, err error) { fs := &helloFS{ Clock: clock, } server = fuseutil.NewFileSystemServer(fs) return }
// Mount the file system based on the supplied arguments, returning a // fuse.MountedFileSystem that can be joined to wait for unmounting. func mount( ctx context.Context, bucketName string, mountPoint string, flags *FlagStorage) (mfs *fuse.MountedFileSystem, err error) { awsConfig := &aws.Config{ Region: &flags.Region, Logger: GetLogger("s3"), //LogLevel: aws.LogLevel(aws.LogDebug), } if len(flags.Profile) > 0 { awsConfig.Credentials = credentials.NewSharedCredentials("", flags.Profile) } if len(flags.Endpoint) > 0 { awsConfig.Endpoint = &flags.Endpoint } // deprecate flags.UsePathRequest if flags.UsePathRequest { log.Infoln("--use-path-request is deprecated, it's always on") } awsConfig.S3ForcePathStyle = aws.Bool(true) goofys := NewGoofys(bucketName, awsConfig, flags) if goofys == nil { err = fmt.Errorf("Mount: initialization failed") return } server := fuseutil.NewFileSystemServer(goofys) fuseLog := GetLogger("fuse") // Mount the file system. mountCfg := &fuse.MountConfig{ FSName: bucketName, Options: flags.MountOptions, ErrorLogger: GetStdLogger(NewLogger("fuse"), logrus.ErrorLevel), DisableWritebackCaching: true, } if flags.DebugFuse { fuseLog.Level = logrus.DebugLevel log.Level = logrus.DebugLevel mountCfg.DebugLogger = GetStdLogger(fuseLog, logrus.DebugLevel) } mfs, err = fuse.Mount(mountPoint, server, mountCfg) if err != nil { err = fmt.Errorf("Mount: %v", err) return } return }
// Create a file system whose sole contents are a file named "foo" and a // directory named "bar". // // The file may be opened for reading and/or writing. Its initial contents are // empty. Whenever a flush or fsync is received, the supplied function will be // called with the current contents of the file and its status returned. // // The directory cannot be modified. func NewFileSystem( reportFlush func(string) error, reportFsync func(string) error) (server fuse.Server, err error) { fs := &flushFS{ reportFlush: reportFlush, reportFsync: reportFsync, } server = fuseutil.NewFileSystemServer(fs) return }
func (t *InterruptFSTest) SetUp(ti *TestInfo) { var err error // Create the file system. t.fs = interruptfs.New() AssertEq(nil, err) t.Server = fuseutil.NewFileSystemServer(t.fs) // Mount it. t.SampleTest.SetUp(ti) }
// Mount the file system based on the supplied arguments, returning a // fuse.MountedFileSystem that can be joined to wait for unmounting. func mount( ctx context.Context, bucketName string, mountPoint string, flags *flagStorage) (mfs *fuse.MountedFileSystem, err error) { // Choose UID and GID. uid, gid, err := MyUserAndGroup() if err != nil { err = fmt.Errorf("MyUserAndGroup: %v", err) return } if flags.Uid >= 0 { uid = uint32(flags.Uid) } if flags.Gid >= 0 { gid = uint32(flags.Gid) } if err != nil { err = fmt.Errorf("setUpBucket: %v", err) return } awsConfig := &aws.Config{ Region: aws.String("us-west-2"), //LogLevel: aws.LogLevel(aws.LogDebug), } server := fuseutil.NewFileSystemServer(NewGoofys(bucketName, awsConfig, uid, gid)) // Mount the file system. mountCfg := &fuse.MountConfig{ FSName: bucketName, Options: flags.MountOptions, ErrorLogger: log.New(os.Stderr, "fuse: ", log.Flags()), } if flags.DebugFuse { mountCfg.DebugLogger = log.New(os.Stderr, "fuse_debug: ", 0) } mfs, err = fuse.Mount(mountPoint, server, mountCfg) if err != nil { err = fmt.Errorf("Mount: %v", err) return } return }
func (s *GoofysTest) mount(t *C, mountPoint string) { server := fuseutil.NewFileSystemServer(s.fs) // Mount the file system. mountCfg := &fuse.MountConfig{ FSName: s.fs.bucket, Options: s.fs.flags.MountOptions, ErrorLogger: GetStdLogger(NewLogger("fuse"), logrus.ErrorLevel), DisableWritebackCaching: true, } _, err := fuse.Mount(mountPoint, server, mountCfg) t.Assert(err, IsNil) }
func (t *TraceFS) Mount() (*fuse.MountedFileSystem, error) { r, _ := t.newTrace(nil, "Mount", "Path=%s", t.MountPath) defer r.Finish() server := fuseutil.NewFileSystemServer(t) fs, err := fuse.Mount(t.MountPath, server, t.MountConfig) if err != nil { r.LazyPrintf("KodingNetworkFS#Mount: err '%s'", err) r.SetError() return nil, err } return fs, nil }
// Mount the file system based on the supplied arguments, returning a // fuse.MountedFileSystem that can be joined to wait for unmounting. func mount( ctx context.Context, bucketName string, mountPoint string, flags *FlagStorage) (mfs *fuse.MountedFileSystem, err error) { awsConfig := &aws.Config{ Region: aws.String("us-west-2"), Logger: GetLogger("s3"), //LogLevel: aws.LogLevel(aws.LogDebug), } if len(flags.Endpoint) > 0 { awsConfig.Endpoint = &flags.Endpoint } if flags.UsePathRequest { awsConfig.S3ForcePathStyle = aws.Bool(true) } goofys := NewGoofys(bucketName, awsConfig, flags) if goofys == nil { err = fmt.Errorf("Mount: initialization failed") return } server := fuseutil.NewFileSystemServer(goofys) fuseLog := GetLogger("fuse") // Mount the file system. mountCfg := &fuse.MountConfig{ FSName: bucketName, Options: flags.MountOptions, ErrorLogger: GetStdLogger(NewLogger("fuse"), logrus.ErrorLevel), DisableWritebackCaching: true, } if flags.DebugFuse { fuseLog.Level = logrus.DebugLevel mountCfg.DebugLogger = GetStdLogger(fuseLog, logrus.DebugLevel) } mfs, err = fuse.Mount(mountPoint, server, mountCfg) if err != nil { err = fmt.Errorf("Mount: %v", err) return } return }
// Create a file system whose sole contents are a file named "foo" and a // directory named "bar". // // The file "foo" may be opened for reading and/or writing, but reads and // writes aren't supported. Additionally, any non-existent file or directory // name may be created within any directory, but the resulting inode will // appear to have been unlinked immediately. // // The file system maintains reference counts for the inodes involved. It will // panic if a reference count becomes negative or if an inode ID is re-used // after we expect it to be dead. Its Check method may be used to check that // there are no inodes with unexpected reference counts remaining, after // unmounting. func NewFileSystem() (fs *ForgetFS) { // Set up the actual file system. impl := &fsImpl{ inodes: map[fuseops.InodeID]*inode{ cannedID_Root: &inode{ attributes: fuseops.InodeAttributes{ Nlink: 1, Mode: 0777 | os.ModeDir, }, }, cannedID_Foo: &inode{ attributes: fuseops.InodeAttributes{ Nlink: 1, Mode: 0777, }, }, cannedID_Bar: &inode{ attributes: fuseops.InodeAttributes{ Nlink: 1, Mode: 0777 | os.ModeDir, }, }, }, nextInodeID: cannedID_Next, } // The root inode starts with a lookup count of one. impl.inodes[cannedID_Root].IncrementLookupCount() // The canned inodes are supposed to be stable from the user's point of view, // so we should allow them to be looked up at any point even if the kernel // has balanced its lookups with its forgets. Ensure that they never go to // zero until the file system is destroyed. impl.inodes[cannedID_Foo].IncrementLookupCount() impl.inodes[cannedID_Bar].IncrementLookupCount() // Set up the mutex. impl.mu = syncutil.NewInvariantMutex(impl.checkInvariants) // Set up a wrapper that exposes only certain methods. fs = &ForgetFS{ impl: impl, server: fuseutil.NewFileSystemServer(impl), } return }
func TestNonEmptyMountPoint(t *testing.T) { ctx := context.Background() // osxfuse appears to be happy to mount over a non-empty mount point. // // We leave this test in for Linux, because it tickles the behavior of // fusermount writing to stderr and exiting with an error code. We want to // make sure that a descriptive error makes it back to the user. if runtime.GOOS == "darwin" { return } // Set up a temporary directory. dir, err := ioutil.TempDir("", "mount_test") if err != nil { t.Fatal("ioutil.TempDir: %v", err) } defer os.RemoveAll(dir) // Add a file within it. err = ioutil.WriteFile(path.Join(dir, "foo"), []byte{}, 0600) if err != nil { t.Fatalf("ioutil.WriteFile: %v", err) } // Attempt to mount. fs := &minimalFS{} mfs, err := fuse.Mount( dir, fuseutil.NewFileSystemServer(fs), &fuse.MountConfig{}) if err == nil { fuse.Unmount(mfs.Dir()) mfs.Join(ctx) t.Fatal("fuse.Mount returned nil") } const want = "not empty" if got := err.Error(); !strings.Contains(got, want) { t.Errorf("Unexpected error: %v", got) } }
func (s *GoofysTest) runFuseTest(t *C, mountPoint string, umount bool, cmdArgs ...string) { server := fuseutil.NewFileSystemServer(s.fs) // Mount the file system. mountCfg := &fuse.MountConfig{ FSName: s.fs.bucket, Options: s.fs.flags.MountOptions, ErrorLogger: GetStdLogger(NewLogger("fuse"), logrus.ErrorLevel), DisableWritebackCaching: true, } _, err := fuse.Mount(mountPoint, server, mountCfg) t.Assert(err, IsNil) if umount { defer func() { err := fuse.Unmount(mountPoint) t.Assert(err, IsNil) }() } cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...) cmd.Env = append(cmd.Env, os.Environ()...) cmd.Env = append(cmd.Env, "TRAVIS=true") cmd.Env = append(cmd.Env, "FAST=true") if isTravis() { logger := NewLogger("test") lvl := logrus.InfoLevel logger.Formatter.(*logHandle).lvl = &lvl w := logger.Writer() cmd.Stdout = w cmd.Stderr = w } err = cmd.Run() t.Assert(err, IsNil) }
func MakeDirDeviceNotConfigured(p string) error { niFs := &NotImplementedFileSystem{&fuseutil.NotImplementedFileSystem{}} config := &fuse.MountConfig{} server := fuseutil.NewFileSystemServer(niFs) f, err := fuse.Mount(p, server, config) if err != nil { return err } go f.Join(context.TODO()) // Sleep to give to mount time to execute. time.Sleep(100 * time.Millisecond) // Reading from it will cause the fs to crash, like we want. if _, err = ioutil.ReadDir(p); err == nil { // ReadDir should error with the panic from niFs.ReadDir, if it doesn't, return // an error. return errors.New("Expected ReadDir op to fail, but it did not.") } return nil }
func (t *cachingFSTest) setUp( ti *TestInfo, lookupEntryTimeout time.Duration, getattrTimeout time.Duration) { var err error // We assert things about whether or not mtimes are cached, but writeback // caching causes them to always be cached. Turn it off. t.MountConfig.DisableWritebackCaching = true // Create the file system. t.fs, err = cachingfs.NewCachingFS(lookupEntryTimeout, getattrTimeout) AssertEq(nil, err) t.Server = fuseutil.NewFileSystemServer(t.fs) // Mount it. t.SampleTest.SetUp(ti) // Set up the mtime. t.initialMtime = time.Date(2012, 8, 15, 22, 56, 0, 0, time.Local) t.fs.SetMtime(t.initialMtime) }
// Create a file system that stores data and metadata in memory. // // The supplied UID/GID pair will own the root inode. This file system does no // permissions checking, and should therefore be mounted with the // default_permissions option. func NewMemFS( uid uint32, gid uint32) fuse.Server { // Set up the basic struct. fs := &memFS{ inodes: make([]*inode, fuseops.RootInodeID+1), uid: uid, gid: gid, } // Set up the root inode. rootAttrs := fuseops.InodeAttributes{ Mode: 0700 | os.ModeDir, Uid: uid, Gid: gid, } fs.inodes[fuseops.RootInodeID] = newInode(rootAttrs) // Set up invariant checking. fs.mu = syncutil.NewInvariantMutex(fs.checkInvariants) return fuseutil.NewFileSystemServer(fs) }
func (t *StatFSTest) SetUp(ti *TestInfo) { var err error // Writeback caching can ruin our measurement of the write sizes the kernel // decides to give us, since it causes write acking to race against writes // being issued from the client. t.MountConfig.DisableWritebackCaching = true // Configure names. t.MountConfig.FSName = fsName t.MountConfig.VolumeName = volumeName // Create the file system. t.fs = statfs.New() t.Server = fuseutil.NewFileSystemServer(t.fs) // Mount it. t.SampleTest.SetUp(ti) // Canonicalize the mount point. t.canonicalDir, err = filepath.EvalSymlinks(t.Dir) AssertEq(nil, err) t.canonicalDir = path.Clean(t.canonicalDir) }
// Mount the file system based on the supplied arguments, returning a // fuse.MountedFileSystem that can be joined to wait for unmounting. func mount( ctx context.Context, bucketName string, mountPoint string, flags *FlagStorage) (mfs *fuse.MountedFileSystem, err error) { ossvfs := NewOssvfs(bucketName, flags) if ossvfs == nil { err = fmt.Errorf("Mount: initialization failed") return } server := fuseutil.NewFileSystemServer(ossvfs) fuseLog := GetLogger("fuse") // Mount the file system. mountCfg := &fuse.MountConfig{ FSName: bucketName, Options: flags.MountOptions, ErrorLogger: GetStdLogger(NewLogger("fuse"), logrus.ErrorLevel), DisableWritebackCaching: true, } if flags.DebugFuse { fuseLog.Level = logrus.DebugLevel mountCfg.DebugLogger = GetStdLogger(fuseLog, logrus.DebugLevel) } mfs, err = fuse.Mount(mountPoint, server, mountCfg) if err != nil { err = fmt.Errorf("Mount: %v", err) return } return }
// Create a fuse file system server according to the supplied configuration. func NewServer(cfg *ServerConfig) (server fuse.Server, err error) { // Check permissions bits. if cfg.FilePerms&^os.ModePerm != 0 { err = fmt.Errorf("Illegal file perms: %v", cfg.FilePerms) return } if cfg.DirPerms&^os.ModePerm != 0 { err = fmt.Errorf("Illegal dir perms: %v", cfg.FilePerms) return } // Create the object syncer. if cfg.TmpObjectPrefix == "" { err = errors.New("You must set TmpObjectPrefix.") return } syncer := gcsx.NewSyncer( cfg.AppendThreshold, cfg.TmpObjectPrefix, cfg.Bucket) // Set up the basic struct. fs := &fileSystem{ mtimeClock: timeutil.RealClock(), cacheClock: cfg.CacheClock, bucket: cfg.Bucket, syncer: syncer, tempDir: cfg.TempDir, implicitDirs: cfg.ImplicitDirectories, inodeAttributeCacheTTL: cfg.InodeAttributeCacheTTL, dirTypeCacheTTL: cfg.DirTypeCacheTTL, uid: cfg.Uid, gid: cfg.Gid, fileMode: cfg.FilePerms, dirMode: cfg.DirPerms | os.ModeDir, inodes: make(map[fuseops.InodeID]inode.Inode), nextInodeID: fuseops.RootInodeID + 1, generationBackedInodes: make(map[string]inode.GenerationBackedInode), implicitDirInodes: make(map[string]inode.DirInode), handles: make(map[fuseops.HandleID]interface{}), } // Set up the root inode. root := inode.NewDirInode( fuseops.RootInodeID, "", // name fuseops.InodeAttributes{ Uid: fs.uid, Gid: fs.gid, Mode: fs.dirMode, }, fs.implicitDirs, fs.dirTypeCacheTTL, cfg.Bucket, fs.mtimeClock, fs.cacheClock) root.Lock() root.IncrementLookupCount() fs.inodes[fuseops.RootInodeID] = root fs.implicitDirInodes[root.Name()] = root root.Unlock() // Set up invariant checking. fs.mu = syncutil.NewInvariantMutex(fs.checkInvariants) // Periodically garbage collect temporary objects. var gcCtx context.Context gcCtx, fs.stopGarbageCollecting = context.WithCancel(context.Background()) go garbageCollect(gcCtx, cfg.TmpObjectPrefix, fs.bucket) server = fuseutil.NewFileSystemServer(fs) return }
// Mount mounts an specified folder on user VM using Fuse in the specificed // local path. func (k *KodingNetworkFS) Mount() (*fuse.MountedFileSystem, error) { server := fuseutil.NewFileSystemServer(k) return fuse.Mount(k.MountPath, server, k.MountConfig) }