Exemple #1
0
// Creates 3 directories on a temporary dir: /mnt with the overlayed
// (unionfs) mount, rw with modifiable data, and ro on the bottom.
func setupUfs(t *testing.T) (workdir string, cleanup func()) {
	// Make sure system setting does not affect test.
	syscall.Umask(0)

	wd, _ := ioutil.TempDir("", "unionfs")
	err := os.Mkdir(wd+"/mnt", 0700)
	if err != nil {
		t.Fatalf("Mkdir failed: %v", err)
	}

	err = os.Mkdir(wd+"/rw", 0700)
	if err != nil {
		t.Fatalf("Mkdir failed: %v", err)
	}

	os.Mkdir(wd+"/ro", 0700)
	if err != nil {
		t.Fatalf("Mkdir failed: %v", err)
	}

	var fses []pathfs.FileSystem
	fses = append(fses, pathfs.NewLoopbackFileSystem(wd+"/rw"))
	fses = append(fses,
		NewCachingFileSystem(pathfs.NewLoopbackFileSystem(wd+"/ro"), 0))
	ufs, err := NewUnionFs(fses, testOpts)
	if err != nil {
		t.Fatalf("NewUnionFs: %v", err)
	}
	// We configure timeouts are smaller, so we can check for
	// UnionFs's cache consistency.
	opts := &nodefs.Options{
		EntryTimeout:    entryTtl / 2,
		AttrTimeout:     entryTtl / 2,
		NegativeTimeout: entryTtl / 2,
		PortableInodes:  true,
	}

	pathfs := pathfs.NewPathNodeFs(ufs,
		&pathfs.PathNodeFsOptions{ClientInodes: true})
	state, conn, err := nodefs.MountRoot(wd+"/mnt", pathfs.Root(), opts)
	if err != nil {
		t.Fatalf("MountNodeFileSystem failed: %v", err)
	}
	conn.SetDebug(VerboseTest())
	state.SetDebug(VerboseTest())
	pathfs.SetDebug(VerboseTest())
	go state.Serve()

	return wd, func() {
		err := state.Unmount()
		if err != nil {
			return
		}
		setRecursiveWritable(t, wd, true)
		os.RemoveAll(wd)
	}
}
Exemple #2
0
func main() {
	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 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,
		Options: nodefs.Options{
			EntryTimeout:    time.Second,
			AttrTimeout:     time.Second,
			NegativeTimeout: time.Second,
			Owner:           fuse.CurrentOwner(),
		},
		UpdateOnMount: true,
		PathNodeFsOptions: pathfs.PathNodeFsOptions{
			ClientInodes: *hardlinks,
		},
		HideReadonly: *hide_readonly_link,
	}
	fsOpts := nodefs.Options{
		PortableInodes: *portableInodes,
	}
	gofs := unionfs.NewAutoUnionFs(flag.Arg(1), options)
	pathfs := pathfs.NewPathNodeFs(gofs, nil)
	state, conn, err := nodefs.MountRoot(flag.Arg(0), pathfs.Root(), &fsOpts)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	pathfs.SetDebug(*debug)
	conn.SetDebug(*debug)
	state.SetDebug(*debug)

	state.Serve()
	time.Sleep(1 * time.Second)
}
func TestXAttrCaching(t *testing.T) {
	wd, _ := ioutil.TempDir("", "unionfs")
	defer os.RemoveAll(wd)
	os.Mkdir(wd+"/mnt", 0700)
	err := os.Mkdir(wd+"/rw", 0700)
	if err != nil {
		t.Fatalf("Mkdir failed: %v", err)
	}

	rwFS := pathfs.NewLoopbackFileSystem(wd + "/rw")
	roFS := &TestFS{
		FileSystem: pathfs.NewDefaultFileSystem(),
	}

	ufs, err := NewUnionFs([]pathfs.FileSystem{rwFS,
		NewCachingFileSystem(roFS, entryTtl)}, testOpts)
	if err != nil {
		t.Fatalf("NewUnionFs: %v", err)
	}

	opts := &nodefs.Options{
		EntryTimeout:    entryTtl / 2,
		AttrTimeout:     entryTtl / 2,
		NegativeTimeout: entryTtl / 2,
	}

	pathfs := pathfs.NewPathNodeFs(ufs,
		&pathfs.PathNodeFsOptions{ClientInodes: true})

	server, conn, err := nodefs.MountRoot(wd+"/mnt", pathfs.Root(), opts)
	if err != nil {
		t.Fatalf("MountNodeFileSystem failed: %v", err)
	}
	server.SetDebug(VerboseTest())
	conn.SetDebug(VerboseTest())
	pathfs.SetDebug(VerboseTest())
	defer server.Unmount()
	go server.Serve()

	if fi, err := os.Lstat(wd + "/mnt"); err != nil || !fi.IsDir() {
		t.Fatalf("root not readable: %v, %v", err, fi)
	}

	buf := make([]byte, 1024)
	n, err := syscall.Getxattr(wd+"/mnt/file", "user.attr", buf)
	if err != nil {
		t.Fatalf("Getxattr: %v", err)
	}
	want := "\x2a"
	got := string(buf[:n])
	if got != want {
		t.Fatalf("Got %q want %q", got, err)
	}
	time.Sleep(entryTtl / 2)
	n, err = syscall.Getxattr(wd+"/mnt/file", "user.attr", buf)
	if err != nil {
		t.Fatalf("Getxattr: %v", err)
	}
	got = string(buf[:n])
	if got != want {
		t.Fatalf("Got %q want %q", got, err)
	}
	server.Unmount()
	if roFS.xattrRead != 1 {
		t.Errorf("got xattrRead=%d, want 1", roFS.xattrRead)
	}
}