示例#1
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)
	fs := fuse.NewMemNodeFs(prefix)
	conn := fuse.NewFileSystemConnector(fs, nil)
	state := fuse.NewMountState(conn)
	state.Debug = *debug

	fmt.Println("Mounting")
	err := state.Mount(mountPoint, nil)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("Mounted!")
	state.Loop()
}
示例#2
0
文件: task.go 项目: krasin/termite
func (me *WorkerDaemon) newWorkerTask(req *WorkRequest, rep *WorkReply) (*WorkerTask, os.Error) {
	fs, err := me.getFileServer(req.FileServer)
	if err != nil {
		return nil, err
	}

	w := &WorkerTask{
		WorkRequest: req,
		WorkReply:   rep,
		daemon:      me,
	}

	tmpDir, err := ioutil.TempDir("", "rpcfs-tmp")
	type dirInit struct {
		dst *string
		val string
	}

	for _, v := range []dirInit{
		dirInit{&w.rwDir, "rw"},
		dirInit{&w.mount, "mnt"},
	} {
		*v.dst = filepath.Join(tmpDir, v.val)
		err = os.Mkdir(*v.dst, 0700)
		if err != nil {
			return nil, err
		}
	}

	rwFs := fuse.NewLoopbackFileSystem(w.rwDir)
	roFs := NewRpcFs(fs, me.contentCache)

	// High ttl, since all writes come through fuse.
	ttl := 100.0
	opts := unionfs.UnionFsOptions{
		BranchCacheTTLSecs:   ttl,
		DeletionCacheTTLSecs: ttl,
		DeletionDirName:      _DELETIONS,
	}
	mOpts := fuse.FileSystemOptions{
		EntryTimeout:    ttl,
		AttrTimeout:     ttl,
		NegativeTimeout: ttl,
	}

	ufs := unionfs.NewUnionFs("ufs", []fuse.FileSystem{rwFs, roFs}, opts)
	conn := fuse.NewFileSystemConnector(ufs, &mOpts)
	state := fuse.NewMountState(conn)
	state.Mount(w.mount, &fuse.MountOptions{AllowOther: true})
	if err != nil {
		return nil, err
	}

	w.MountState = state
	go state.Loop(true)
	return w, nil
}
示例#3
0
func main() {
	fsdebug := flag.Bool("fs-debug", false, "switch on FS debugging")
	mtpDebug := flag.Bool("mtp-debug", false, "switch on MTP debugging")
	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 devices.")
	storageFilter := flag.String("storage", "", "regular expression to filter storage areas.")
	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()

	if err = dev.OpenSession(); err != nil {
		log.Fatalf("OpenSession failed: %v", err)
	}

	sids, err := fs.SelectStorages(dev, *storageFilter)
	if err != nil {
		log.Fatalf("selectStorages failed: %v", err)
	}

	dev.DebugPrint = *mtpDebug
	opts := fs.DeviceFsOptions{
		RemovableVFat: *vfat,
	}
	fs, err := fs.NewDeviceFs(dev, sids, opts)
	if err != nil {
		log.Fatalf("NewDeviceFs failed: %v", err)
	}
	conn := fuse.NewFileSystemConnector(fs, fuse.NewFileSystemOptions())
	rawFs := fuse.NewLockingRawFileSystem(conn)

	mount := fuse.NewMountState(rawFs)
	mOpts := &fuse.MountOptions{
		AllowOther: *other,
	}
	if err := mount.Mount(mountpoint, mOpts); err != nil {
		log.Fatalf("mount failed: %v", err)
	}

	conn.Debug = *fsdebug
	mount.Debug = *fsdebug
	log.Printf("starting FUSE %v", fuse.Version())
	mount.Loop()
}
示例#4
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 fuse.FileSystem
	orig := flag.Arg(1)
	loopbackfs := fuse.NewLoopbackFileSystem(orig)
	finalFs = loopbackfs

	opts := &fuse.FileSystemOptions{
		// These options are to be compatible with libfuse defaults,
		// making benchmarking easier.
		NegativeTimeout: time.Second,
		AttrTimeout:     time.Second,
		EntryTimeout:    time.Second,
	}
	pathFs := fuse.NewPathNodeFs(finalFs, nil)
	conn := fuse.NewFileSystemConnector(pathFs, opts)
	state := fuse.NewMountState(conn)
	state.Debug = *debug

	mountPoint := flag.Arg(0)

	fmt.Println("Mounting")
	mOpts := &fuse.MountOptions{
		AllowOther: *other,
	}
	err := state.Mount(mountPoint, mOpts)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("Mounted!")
	state.Loop()
}
示例#5
0
文件: main.go 项目: krasin/termite
func main() {
	cachedir := flag.String("cachedir", "/tmp/termite-cache", "content cache")
	server := flag.String("server", "localhost:1234", "file server")
	secretFile := flag.String("secret", "/tmp/secret.txt", "file containing password.")

	flag.Parse()
	if flag.NArg() < 1 {
		fmt.Fprintf(os.Stderr, "usage: %s MOUNTPOINT\n", os.Args[0])
		os.Exit(2)
	}
	secret, err := ioutil.ReadFile(*secretFile)
	if err != nil {
		log.Fatal("ReadFile", err)
	}

	rpcConn, err := termite.SetupClient(*server, secret)
	if err != nil {
		log.Fatal("dialing:", err)
	}

	var fs fuse.FileSystem
	cache := termite.NewDiskFileCache(*cachedir)
	fs = termite.NewRpcFs(rpc.NewClient(rpcConn), cache)
	conn := fuse.NewFileSystemConnector(fs, nil)
	state := fuse.NewMountState(conn)
	opts := fuse.MountOptions{}
	if os.Geteuid() == 0 {
		opts.AllowOther = true
	}

	state.Mount(flag.Arg(0), &opts)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	state.Debug = true
	state.Loop(false)
}
示例#6
0
func MountVfs(databasePath string, mountPath string, allowOther bool) (*FuseVfs, error) {
	fuseVfs := FuseVfs{}
	pathNodeFs := fuse.NewPathNodeFs(&fuseVfs, nil)
	conn := fuse.NewFileSystemConnector(pathNodeFs, nil)
	state := fuse.NewMountState(conn)

	mountOptions := fuse.MountOptions{AllowOther: allowOther}
	err := state.Mount(mountPath, &mountOptions)
	if err != nil {
		return nil, fmt.Errorf("could not mount virtual filesystem at '%v': %v", mountPath, err)
	}

	store, err := storage.OpenAt(databasePath)
	if err != nil {
		return nil, fmt.Errorf("could not open database at '%v': %v", databasePath, err)
	}

	fuseVfs.store = store
	fuseVfs.mountPath = mountPath
	fuseVfs.state = state

	return &fuseVfs, nil
}
示例#7
0
文件: main.go 项目: xushiwei/go-mtpfs
func main() {
	fsdebug := flag.Bool("fs-debug", false, "switch on FS debugging")
	mtpDebug := flag.Int("mtp-debug", 0, "switch on MTP debugging")
	flag.Parse()

	if len(flag.Args()) != 1 {
		log.Fatal("Usage: mtpfs MOUNT-POINT")
	}
	mountpoint := flag.Arg(0)

	Init()
	SetDebug(*mtpDebug)
	devs, err := Detect()
	if err != nil {
		log.Fatalf("detect: %v", err)
	}
	for _, d := range devs {
		log.Printf("device %v: ", d)
	}
	if len(devs) == 0 {
		log.Fatal("no device found.  Try replugging it.")
	}
	if len(devs) > 1 {
		log.Fatal("must have exactly one device")
	}

	rdev := devs[0]

	dev, err := rdev.Open()
	if err != nil {
		log.Fatalf("rdev.open: %v", err)
	}
	defer dev.Release()
	dev.GetStorage(0)
	for _, s := range dev.ListStorage() {
		log.Printf("storage ID %d: %s", s.Id(), s.Description())
	}

	if len(dev.ListStorage()) == 0 {
		log.Fatalf("No storages found.  Try unlocking the device.")
	}

	backing, err := ioutil.TempDir("", "go-mtpfs")
	if err != nil {
		log.Fatalf("TempDir failed: %v", err)
	}
	fs := NewDeviceFs(dev, backing)
	conn := fuse.NewFileSystemConnector(fs, fuse.NewFileSystemOptions())
	rawFs := fuse.NewLockingRawFileSystem(conn)

	mount := fuse.NewMountState(rawFs)
	if err := mount.Mount(mountpoint, nil); err != nil {
		log.Fatalf("mount failed: %v", err)
	}

	conn.Debug = *fsdebug
	mount.Debug = *fsdebug
	log.Println("starting FUSE.")
	mount.Loop()
	os.RemoveAll(backing)
}
示例#8
0
文件: main.go 项目: thomasf/go-mtpfs
func main() {
	fsdebug := flag.Bool("fs-debug", false, "switch on FS debugging")
	mtpDebug := flag.Int("mtp-debug", 0, "switch on MTP debugging. 1=PTP, 2=PLST, 4=USB, 8=DATA")
	backing := flag.String("backing-dir", "", "backing store for locally cached files. Default: use a temporary directory.")
	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 devices.")
	storageFilter := flag.String("storage", "", "regular expression to filter storage areas.")
	flag.Parse()

	if len(flag.Args()) != 1 {
		log.Fatalf("Usage: %s [options] MOUNT-POINT\n", os.Args[0])
	}
	mountpoint := flag.Arg(0)

	Init()
	SetDebug(*mtpDebug)
	devs, err := Detect()
	if err != nil {
		log.Fatalf("detect failed: %v", err)
	}

	if *deviceFilter != "" {
		re, err := regexp.Compile(*deviceFilter)
		if err != nil {
			log.Fatalf("invalid regexp %q: %v", *deviceFilter, err)
		}
		filtered := []*RawDevice{}
		for _, d := range devs {
			if re.FindStringIndex(d.String()) != nil {
				filtered = append(filtered, d)
			} else {
				log.Printf("filtering out device %v: ", d)
			}
		}
		devs = filtered
	} else {
		for _, d := range devs {
			log.Printf("found device %v: ", d)
		}
	}

	if len(devs) == 0 {
		log.Fatal("no device found.  Try replugging it.")
	}
	if len(devs) > 1 {
		log.Fatal("must have exactly one device. Try using -dev")
	}

	rdev := devs[0]

	dev, err := rdev.Open()
	if err != nil {
		log.Fatalf("rdev.open failed: %v", err)
	}
	defer dev.Release()
	dev.GetStorage(0)

	storages := []*DeviceStorage{}
	for _, s := range dev.ListStorage() {
		if !s.IsHierarchical() {
			log.Printf("skipping non hierarchical storage %q", s.Description())
			continue
		}
		storages = append(storages, s)
	}

	if *storageFilter != "" {
		re, err := regexp.Compile(*storageFilter)
		if err != nil {
			log.Fatalf("invalid regexp %q: %v", *storageFilter, err)
		}

		filtered := []*DeviceStorage{}
		for _, s := range storages {
			if re.FindStringIndex(s.Description()) == nil {
				log.Printf("filtering out storage %q", s.Description())
				continue
			}
			filtered = append(filtered, s)
		}

		if len(filtered) == 0 {
			log.Fatalf("No storages found. Try changing the -storage flag.")
		}
		storages = filtered
	} else {
		for _, s := range storages {
			log.Printf("storage ID %d: %s", s.Id(), s.Description())
		}
	}

	if len(storages) == 0 {
		log.Fatalf("No storages found. Try unlocking the device.")
	}

	if *backing == "" {
		*backing, err = ioutil.TempDir("", "go-mtpfs")
		if err != nil {
			log.Fatalf("TempDir failed: %v", err)
		}
	} else {
		*backing = *backing + "/go-mtpfs"
		err = os.Mkdir(*backing, 0700)
		if err != nil {
			log.Fatalf("Mkdir failed: %v", err)
		}
	}
	log.Println("backing data", *backing)
	defer os.RemoveAll(*backing)

	opts := DeviceFsOptions{
		Dir:           *backing,
		RemovableVFat: *vfat,
	}
	fs := NewDeviceFs(dev, storages, opts)
	conn := fuse.NewFileSystemConnector(fs, fuse.NewFileSystemOptions())
	rawFs := fuse.NewLockingRawFileSystem(conn)

	mount := fuse.NewMountState(rawFs)
	mOpts := &fuse.MountOptions{
		AllowOther: *other,
	}
	if err := mount.Mount(mountpoint, mOpts); err != nil {
		log.Fatalf("mount failed: %v", err)
	}

	conn.Debug = *fsdebug
	mount.Debug = *fsdebug
	log.Printf("starting FUSE %v", fuse.Version())
	mount.Loop()
}
示例#9
0
func main() {
	fsdebug := flag.Bool("fs-debug", false, "switch on FS debugging")
	mtpDebug := flag.Int("mtp-debug", 0, "switch on MTP debugging. 1=PTP, 2=PLST, 4=USB, 8=DATA")
	backing := flag.String("backing-dir", "", "backing store for locally cached files. Default: use a temporary directory.")
	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.")
	flag.Parse()

	if len(flag.Args()) != 1 {
		log.Fatal("Usage: mtpfs MOUNT-POINT")
	}
	mountpoint := flag.Arg(0)

	Init()
	SetDebug(*mtpDebug)
	devs, err := Detect()
	if err != nil {
		log.Fatalf("detect: %v", err)
	}
	for _, d := range devs {
		log.Printf("device %v: ", d)
	}
	if len(devs) == 0 {
		log.Fatal("no device found.  Try replugging it.")
	}
	if len(devs) > 1 {
		log.Fatal("must have exactly one device")
	}

	rdev := devs[0]

	dev, err := rdev.Open()
	if err != nil {
		log.Fatalf("rdev.open: %v", err)
	}
	defer dev.Release()
	dev.GetStorage(0)
	for _, s := range dev.ListStorage() {
		log.Printf("storage ID %d: %s", s.Id(), s.Description())
	}

	if len(dev.ListStorage()) == 0 {
		log.Fatalf("No storages found.  Try unlocking the device.")
	}

	if *backing == "" {
		*backing, err = ioutil.TempDir("", "go-mtpfs")
		if err != nil {
			log.Fatalf("TempDir failed: %v", err)
		}
	} else {
		*backing = *backing + "/go-mtpfs"
		err = os.Mkdir(*backing, 0700)
		if err != nil {
			log.Fatalf("Mkdir failed: %v", err)
		}
	}
	log.Println("backing data", *backing)
	defer os.RemoveAll(*backing)

	opts := DeviceFsOptions{
		Dir:           *backing,
		RemovableVFat: *vfat,
	}
	fs := NewDeviceFs(dev, &opts)
	conn := fuse.NewFileSystemConnector(fs, fuse.NewFileSystemOptions())
	rawFs := fuse.NewLockingRawFileSystem(conn)

	mount := fuse.NewMountState(rawFs)
	mOpts := &fuse.MountOptions{
		AllowOther: *other,
	}
	if err := mount.Mount(mountpoint, mOpts); err != nil {
		log.Fatalf("mount failed: %v", err)
	}

	conn.Debug = *fsdebug
	mount.Debug = *fsdebug
	log.Println("starting FUSE.")
	mount.Loop()
}
示例#10
0
文件: fuse.go 项目: janneke/termite
func newWorkerFuseFs(tmpDir string, rpcFs fuse.FileSystem, writableRoot string, nobody *User) (*workerFuseFs, error) {
	tmpDir, err := ioutil.TempDir(tmpDir, "termite-task")
	if err != nil {
		return nil, err
	}
	me := &workerFuseFs{
		tmpDir:       tmpDir,
		writableRoot: strings.TrimLeft(writableRoot, "/"),
		tasks:        map[*WorkerTask]bool{},
	}

	type dirInit struct {
		dst *string
		val string
	}

	tmpBacking := ""
	for _, v := range []dirInit{
		{&me.rwDir, "rw"},
		{&me.mount, "mnt"},
		{&tmpBacking, "tmp-backing"},
	} {
		*v.dst = filepath.Join(me.tmpDir, v.val)
		err = os.Mkdir(*v.dst, 0700)
		if err != nil {
			return nil, err
		}
	}

	fuseOpts := fuse.MountOptions{}
	if os.Geteuid() == 0 {
		fuseOpts.AllowOther = true
	}

	me.rpcNodeFs = fuse.NewPathNodeFs(rpcFs, nil)
	ttl := 30 * time.Second
	mOpts := fuse.FileSystemOptions{
		EntryTimeout:    ttl,
		AttrTimeout:     ttl,
		NegativeTimeout: ttl,

		// 32-bit programs have trouble with 64-bit inode
		// numbers.
		PortableInodes: true,
	}

	me.fsConnector = fuse.NewFileSystemConnector(me.rpcNodeFs, &mOpts)
	me.MountState = fuse.NewMountState(me.fsConnector)
	err = me.MountState.Mount(me.mount, &fuseOpts)
	if err != nil {
		return nil, err
	}
	go me.MountState.Loop()

	me.unionFs = fs.NewMemUnionFs(
		me.rwDir, &fuse.PrefixFileSystem{rpcFs, me.writableRoot})

	me.procFs = fs.NewProcFs()
	me.procFs.StripPrefix = me.mount
	if nobody != nil {
		me.procFs.Uid = nobody.Uid
	}
	type submount struct {
		mountpoint string
		fs         fuse.NodeFileSystem
	}

	mounts := []submount{
		{"proc", fuse.NewPathNodeFs(me.procFs, nil)},
		{"sys", fuse.NewPathNodeFs(&fuse.ReadonlyFileSystem{fuse.NewLoopbackFileSystem("/sys")}, nil)},
		{"tmp", fuse.NewMemNodeFs(tmpBacking + "/tmp")},
		{"dev", fs.NewDevNullFs()},
		{"var/tmp", fuse.NewMemNodeFs(tmpBacking + "/vartmp")},
	}
	for _, s := range mounts {
		subOpts := &mOpts
		if s.mountpoint == "proc" {
			subOpts = nil
		}

		code := me.rpcNodeFs.Mount(s.mountpoint, s.fs, subOpts)
		if !code.Ok() {
			if err := me.MountState.Unmount(); err != nil {
				log.Fatal("FUSE unmount error during cleanup:", err)
			}
			return nil, errors.New(fmt.Sprintf("submount error for %s: %v", s.mountpoint, code))
		}
	}
	if strings.HasPrefix(me.writableRoot, "tmp/") {
		parent, _ := filepath.Split(me.writableRoot)
		err := os.MkdirAll(filepath.Join(me.mount, parent), 0755)
		if err != nil {
			if err := me.MountState.Unmount(); err != nil {
				log.Fatal("FUSE unmount error during cleanup:", err)
			}
			return nil, errors.New(fmt.Sprintf("Mkdir of %q in /tmp fail: %v", parent, err))
		}
		// This is hackish, but we don't want rpcfs/fsserver
		// getting confused by asking for tmp/foo/bar
		// directly.
		rpcFs.GetAttr("tmp", nil)
		rpcFs.GetAttr(me.writableRoot, nil)
	}
	code := me.rpcNodeFs.Mount(me.writableRoot, me.unionFs, &mOpts)
	if !code.Ok() {
		if err := me.MountState.Unmount(); err != nil {
			log.Fatal("FUSE unmount error during cleanup:", err)
		}
		return nil, errors.New(fmt.Sprintf("submount error for %s: %v", me.writableRoot, code))
	}

	return me, nil
}
示例#11
0
文件: main.go 项目: sneezer/go-mtpfs
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 devices.")
	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 := fuse.NewFileSystemConnector(fs, fuse.NewFileSystemOptions())
	rawFs := fuse.NewLockingRawFileSystem(conn)

	mount := fuse.NewMountState(rawFs)
	mOpts := &fuse.MountOptions{
		AllowOther: *other,
	}
	if err := mount.Mount(mountpoint, mOpts); err != nil {
		log.Fatalf("mount failed: %v", err)
	}

	conn.Debug = debugs["fuse"] || debugs["fs"]
	mount.Debug = debugs["fuse"] || debugs["fs"]
	log.Printf("starting FUSE %v", fuse.Version())
	mount.Loop()
	fs.OnUnmount()
}
示例#12
0
func main() {
	// Scans the arg list and sets up flags
	debug := flag.Bool("debug", false, "print debugging messages.")
	latencies := flag.Bool("latencies", false, "record latencies.")
	threaded := flag.Bool("threaded", true, "switch off threading; print debugging messages.")
	flag.Parse()
	if flag.NArg() < 2 {
		// TODO - where to get program name?
		fmt.Println("usage: main MOUNTPOINT ORIGINAL")
		os.Exit(2)
	}

	var finalFs fuse.FileSystem
	orig := flag.Arg(1)
	loopbackfs := fuse.NewLoopbackFileSystem(orig)
	finalFs = loopbackfs

	debugFs := fuse.NewFileSystemDebug()
	if *latencies {
		timing := fuse.NewTimingFileSystem(finalFs)
		debugFs.AddTimingFileSystem(timing)
		finalFs = timing
	}

	opts := &fuse.FileSystemOptions{
		// These options are to be compatible with libfuse defaults,
		// making benchmarking easier.
		NegativeTimeout: 1.0,
		AttrTimeout:     1.0,
		EntryTimeout:    1.0,
	}

	if *latencies {
		debugFs.FileSystem = finalFs
		finalFs = debugFs
	}

	conn := fuse.NewFileSystemConnector(finalFs, opts)
	var finalRawFs fuse.RawFileSystem = conn
	if *latencies {
		rawTiming := fuse.NewTimingRawFileSystem(conn)
		debugFs.AddRawTimingFileSystem(rawTiming)
		finalRawFs = rawTiming
	}

	state := fuse.NewMountState(finalRawFs)
	state.Debug = *debug

	if *latencies {
		state.SetRecordStatistics(true)
		debugFs.AddMountState(state)
		debugFs.AddFileSystemConnector(conn)
	}
	mountPoint := flag.Arg(0)

	fmt.Println("Mounting")
	err := state.Mount(mountPoint, nil)
	if err != nil {
		fmt.Printf("Mount fail: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("Mounted!")
	state.Loop(*threaded)
}
示例#13
0
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 := fuse.NewFileSystemConnector(fs, fuse.NewFileSystemOptions())
	rawFs := fuse.NewLockingRawFileSystem(conn)
	mount := fuse.NewMountState(rawFs)
	if err := mount.Mount(tempdir, nil); err != nil {
		t.Fatalf("mount failed: %v", err)
	}

	mount.Debug = fuse.VerboseTest()
	dev.MTPDebug = fuse.VerboseTest()
	dev.USBDebug = fuse.VerboseTest()
	dev.DataDebug = fuse.VerboseTest()
	go mount.Loop()

	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()
	}
}
示例#14
0
func TestDevice(t *testing.T) {
	dev, err := mtp.SelectDevice("")
	if err != nil {
		t.Fatalf("detect failed: %v", err)
	}
	defer dev.Close()

	if err = dev.OpenSession(); err != nil {
		t.Fatalf("OpenSession failed: %v", err)
	}

	sids, err := SelectStorages(dev, "")
	if err != nil {
		t.Fatalf("selectStorages failed: %v", err)
	}

	tempdir, err := ioutil.TempDir("", "mtpfs")
	if err != nil {
		t.Fatal(err)
	}
	opts := DeviceFsOptions{}
	fs, err := NewDeviceFs(dev, sids, opts)
	conn := fuse.NewFileSystemConnector(fs, fuse.NewFileSystemOptions())
	rawFs := fuse.NewLockingRawFileSystem(conn)
	mount := fuse.NewMountState(rawFs)
	if err := mount.Mount(tempdir, nil); err != nil {
		t.Fatalf("mount failed: %v", err)
	}

	mount.Debug = true
	dev.DebugPrint = true

	defer mount.Unmount()
	go mount.Loop()

	var root string
	for i := 0; i < 10; i++ {
		fis, err := ioutil.ReadDir(tempdir)
		if err != nil || len(fis) == 0 {
			time.Sleep(1)
			continue
		}

		root = filepath.Join(tempdir, fis[0].Name())
		break
		if i == 9 {
			t.Fatal("mount unsuccessful")
		}
	}

	_, err = os.Lstat(root + "/Music")
	if err != nil {
		t.Fatal("Music not found", err)
	}

	name := filepath.Join(root, fmt.Sprintf("mtpfs-test-%x", rand.Int31()))
	golden := "abcpxq134"
	if err := ioutil.WriteFile(name, []byte("abcpxq134"), 0644); err != nil {
		t.Fatal(err)
	}
	got, err := ioutil.ReadFile(name)
	if err != nil {
		t.Fatal("ReadFile failed", err)
	}

	if string(got) != golden {
		t.Fatalf("got %q, want %q", got, golden)
	}

	f, err := os.OpenFile(name, os.O_RDWR|os.O_APPEND, 0644)
	if err != nil {
		t.Fatal("OpenFile failed:", err)
	}

	log.Println("writing...")
	golden += "hello"
	f.Write([]byte("hello"))
	log.Println("done...")
	f.Close()

	got, err = ioutil.ReadFile(name)
	if err != nil {
		t.Fatal("ReadFile failed", err)
	}

	if string(got) != golden {
		t.Fatalf("got %q, want %q", got, golden)
	}

	newName := filepath.Join(root, fmt.Sprintf("mtpfs-test-%x", rand.Int31()))
	err = os.Rename(name, newName)
	if err != nil {
		t.Fatal("Rename failed", err)
	}

	if fi, err := os.Lstat(name); err == nil {
		t.Fatal("should have disappeared after rename", fi)
	}

	if _, err := os.Lstat(newName); err != nil {
		t.Fatal("should be able to stat after rename", err)
	}

	err = os.Remove(newName)
	if err != nil {
		t.Fatal("Remove failed", err)
	}
	if fi, err := os.Lstat(newName); err == nil {
		t.Fatal("should have disappeared after Remove", fi)
	}
}