Example #1
0
func (fs *AutoUnionFs) GetAttr(path string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
	if path == "" || path == _CONFIG || path == _STATUS {
		a := &fuse.Attr{
			Mode: fuse.S_IFDIR | 0755,
		}
		return a, fuse.OK
	}

	if path == filepath.Join(_STATUS, _DEBUG_SETTING) && fs.hasDebug() {
		return &fuse.Attr{
			Mode: fuse.S_IFLNK | 0644,
		}, fuse.OK
	}

	if path == filepath.Join(_STATUS, _VERSION) {
		a := &fuse.Attr{
			Mode: fuse.S_IFREG | 0644,
			Size: uint64(len(fuse.Version())),
		}
		return a, fuse.OK
	}

	if path == filepath.Join(_STATUS, _DEBUG) {
		a := &fuse.Attr{
			Mode: fuse.S_IFREG | 0644,
			Size: uint64(len(fs.DebugData())),
		}
		return a, fuse.OK
	}

	if path == filepath.Join(_STATUS, _ROOT) {
		a := &fuse.Attr{
			Mode: syscall.S_IFLNK | 0644,
		}
		return a, fuse.OK
	}

	if path == filepath.Join(_CONFIG, _SCAN_CONFIG) {
		a := &fuse.Attr{
			Mode: fuse.S_IFREG | 0644,
		}
		return a, fuse.OK
	}
	comps := strings.Split(path, string(filepath.Separator))

	if len(comps) > 1 && comps[0] == _CONFIG {
		fs := fs.getUnionFs(comps[1])

		if fs == nil {
			return nil, fuse.ENOENT
		}

		a := &fuse.Attr{
			Mode: syscall.S_IFLNK | 0644,
		}
		return a, fuse.OK
	}

	return nil, fuse.ENOENT
}
Example #2
0
func (fs *AutoUnionFs) DebugData() string {
	if fs.mountState == nil {
		return "AutoUnionFs.mountState not set"
	}
	setting := fs.mountState.KernelSettings()
	msg := fmt.Sprintf(
		"Version: %v\n"+
			"Bufferpool: %v\n"+
			"Kernel: %v\n",
		fuse.Version(),
		fs.mountState.BufferPoolStats(),
		&setting)

	if fs.connector != nil {
		msg += fmt.Sprintf("Live inodes: %d\n", fs.connector.InodeHandleCount())
	}

	return msg
}
Example #3
0
func (fs *AutoUnionFs) Open(path string, flags uint32, context *fuse.Context) (fuse.File, fuse.Status) {
	if path == filepath.Join(_STATUS, _DEBUG) {
		if flags&fuse.O_ANYWRITE != 0 {
			return nil, fuse.EPERM
		}

		return fuse.NewDataFile([]byte(fs.DebugData())), fuse.OK
	}
	if path == filepath.Join(_STATUS, _VERSION) {
		if flags&fuse.O_ANYWRITE != 0 {
			return nil, fuse.EPERM
		}
		return fuse.NewDataFile([]byte(fuse.Version())), fuse.OK
	}
	if path == filepath.Join(_CONFIG, _SCAN_CONFIG) {
		if flags&fuse.O_ANYWRITE != 0 {
			fs.updateKnownFses()
		}
		return fuse.NewDevNullFile(), fuse.OK
	}
	return nil, fuse.ENOENT
}
Example #4
0
func main() {
	version := flag.Bool("version", false, "print version number")
	debug := flag.Bool("debug", false, "debug on")
	hardlinks := flag.Bool("hardlinks", false, "support hardlinks")
	delcache_ttl := flag.Float64("deletion_cache_ttl", 5.0, "Deletion cache TTL in seconds.")
	branchcache_ttl := flag.Float64("branchcache_ttl", 5.0, "Branch cache TTL in seconds.")
	deldirname := flag.String(
		"deletion_dirname", "GOUNIONFS_DELETIONS", "Directory name to use for deletions.")
	hide_readonly_link := flag.Bool("hide_readonly_link", true,
		"Hides READONLY link from the top mountpoints. "+
			"Enabled by default.")
	portableInodes := flag.Bool("portable-inodes", false,
		"Use sequential 32-bit inode numbers.")

	flag.Parse()

	if *version {
		fmt.Println(fuse.Version())
		os.Exit(0)
	}

	if len(flag.Args()) < 2 {
		fmt.Println("Usage:\n  main MOUNTPOINT BASEDIR")
		os.Exit(2)
	}
	ufsOptions := unionfs.UnionFsOptions{
		DeletionCacheTTL: time.Duration(*delcache_ttl * float64(time.Second)),
		BranchCacheTTL:   time.Duration(*branchcache_ttl * float64(time.Second)),
		DeletionDirName:  *deldirname,
	}
	options := unionfs.AutoUnionFsOptions{
		UnionFsOptions: ufsOptions,
		FileSystemOptions: fuse.FileSystemOptions{
			EntryTimeout:    time.Second,
			AttrTimeout:     time.Second,
			NegativeTimeout: time.Second,
			Owner:           fuse.CurrentOwner(),
		},
		UpdateOnMount: true,
		PathNodeFsOptions: fuse.PathNodeFsOptions{
			ClientInodes: *hardlinks,
		},
		HideReadonly: *hide_readonly_link,
	}
	fsOpts := fuse.FileSystemOptions{
		PortableInodes: *portableInodes,
	}
	fmt.Printf("AutoUnionFs - Go-FUSE Version %v.\n", fuse.Version())
	gofs := unionfs.NewAutoUnionFs(flag.Arg(1), options)
	pathfs := fuse.NewPathNodeFs(gofs, nil)
	state, conn, err := fuse.MountNodeFileSystem(flag.Arg(0), pathfs, &fsOpts)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	pathfs.Debug = *debug
	conn.Debug = *debug
	state.Debug = *debug

	gofs.SetMountState(state)
	gofs.SetFileSystemConnector(conn)

	state.Loop()
	time.Sleep(1 * time.Second)
}