func main() { flag.Usage = Usage flag.Parse() if flag.NArg() != 1 { Usage() os.Exit(2) } mountpoint := flag.Arg(0) c, err := fuse.Mount( mountpoint, fuse.FSName("helloworld"), fuse.Subtype("hellofs"), fuse.LocalVolume(), fuse.VolumeName("Hello world!"), ) if err != nil { log.Fatal(err) } defer c.Close() err = fs.Serve(c, FS{}) if err != nil { log.Fatal(err) } // check if the mount process has an error to report <-c.Ready if err := c.MountError; err != nil { log.Fatal(err) } }
func TestMountOptionSubtype(t *testing.T) { if runtime.GOOS == "darwin" { t.Skip("OS X does not support Subtype") } if runtime.GOOS == "freebsd" { t.Skip("FreeBSD does not support Subtype") } t.Parallel() const name = "FuseTestMarker" mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}}, nil, fuse.Subtype(name), ) if err != nil { t.Fatal(err) } defer mnt.Close() info, err := fstestutil.GetMountInfo(mnt.Dir) if err != nil { t.Fatal(err) } if g, e := info.Type, "fuse."+name; g != e { t.Errorf("wrong Subtype: %q != %q", g, e) } }
// // Main function. // - Exposes remote FS structure locally using FUSE (bazil-fuse) // - Gets files from remote on-demand // - TODO: // - Check-in files to remote // - Version control // func Revelo(Name string, accType string, cacheDir string, mntDir string) error { GlobalData.metaName = Name + ".meta" acc, err := initAccess(accType, mntDir) if err != nil { log.Errorf("Revelo: Invalid Access type: %v", accType) return err } remoteDir, err := acc.Init() if err != nil { log.WithFields(log.Fields{"Acc": acc, "Error": err}).Error("Revelo: Cannot init access") return err } GlobalData.cacheDir = cacheDir GlobalData.mntDir = mntDir log.WithFields(log.Fields{ "Access": acc, "CacheDir": cacheDir, "mntDir": mntDir, "RemoteDir": remoteDir, }).Info("Revelo - Init done...") _, err = os.Stat(cacheDir + "/" + GlobalData.metaName) // If some error happened here, we might fail in open later. // Its better not to GetFile in that case. // Get meta from <name>.meta file metaPresent := ((err == nil) || !os.IsNotExist(err)) if metaPresent == false { var metaName string if remoteDir == "" { metaName = GlobalData.metaName } else { metaName = remoteDir + "/" + GlobalData.metaName } err = acc.GetFile(metaName, cacheDir+"/"+GlobalData.metaName) if err != nil { log.WithFields(log.Fields{ "Remote": metaName, "Local": cacheDir + "/" + GlobalData.metaName, "AccData": acc, }).Error("Revelo: Cannot get meta file") return err } } else { log.Info("Revelo: Meta file present, using it...") } metaFile, err := os.Open(cacheDir + "/" + GlobalData.metaName) if err != nil { log.WithFields(log.Fields{ "Meta File": cacheDir + "/" + GlobalData.metaName, "Error": err, }).Error("Cannot open meta file") return err } defer metaFile.Close() st, _ := metaFile.Stat() //XXX This should not fail metaData := make([]byte, st.Size()+1) n, err := metaFile.Read(metaData) if err != nil || n == 0 { log.WithFields(log.Fields{ "Meta File": cacheDir + "/" + GlobalData.metaName, "Read bytes": n, "Error": err, }).Error("Revelo: Cannot read meta file, error or empty") return syscall.EINVAL } // Unmarshal the meta data metaData = metaData[:n] meta := new(horcrux.Meta) err = json.Unmarshal(metaData, meta) if err != nil { log.WithFields(log.Fields{ "Meta Data": string(metaData), "Error": err, }).Error("Revelo: Cannot unmarshal meta data") return err } // Create dirTree GlobalData.Root, err = dirTree.Create(meta) GlobalData.Config = meta.Config GlobalData.CurrVer = meta.CurrVer GlobalData.NumFiles = meta.NumFiles // Mount local fuseConn, err := fuse.Mount(mntDir, fuse.FSName("Horcrux"), fuse.Subtype("Horcrux-"+acc.Name()), fuse.MaxReadahead(128*(1<<10)), fuse.AllowOther()) //XXX : Revisit AllowOther if err != nil { log.WithFields(log.Fields{"Conn": fuseConn, "Error": err}).Error("Mount Failed") return err } defer fuseConn.Close() GlobalData.fuseConn = fuseConn log.Debugf("Mount OK: %v", GlobalData.CurrVer) horcruxFS := &FS{Acc: &acc, RData: &GlobalData, remoteDir: remoteDir, cacheDir: cacheDir} err = fs.Serve(fuseConn, horcruxFS) if err != nil { log.WithFields(log.Fields{"Conn": fuseConn, "Error": err}).Error("Cannot fs.Serve") return err } <-fuseConn.Ready if err := fuseConn.MountError; err != nil { log.WithFields(log.Fields{"Conn": fuseConn, "Error": err}).Error("Mount Failed") return err } log.Info("Revelo Done...") return nil }