Example #1
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"

	os.Mkdir(tc.orig, 0700)
	os.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,
		})
	tc.connector.SetDebug(VerboseTest())
	tc.state, err = fuse.NewServer(
		fuse.NewRawFileSystem(tc.connector.RawFS()), tc.mnt, &fuse.MountOptions{SingleThreaded: true})
	if err != nil {
		t.Fatal("NewServer:", err)
	}

	tc.state.SetDebug(VerboseTest())

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

	tc.state.WaitMount()
	return tc
}
Example #2
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()
}
Example #3
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)
	root := nodefs.NewMemNodeFSRoot(prefix)
	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()
}
Example #4
0
func TestDeleteNotify(t *testing.T) {
	dir, err := ioutil.TempDir("", "go-fuse-delete_test")
	if err != nil {
		t.Fatalf("TempDir failed %v", err)
	}
	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, nil)
	if err != nil {
		t.Fatal(err)
	}
	state.SetDebug(VerboseTest())
	go state.Serve()
	defer state.Unmount()

	_, 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)
	}
}