func lfscache(t zx.Tree, fn func()) (zx.Tree, func(), error) { m, err := lfs.New("clfs", lfsdir, lfs.RW) if err != nil { return nil, nil, fmt.Errorf("lfs", err) } m.SaveAttrs(true) m.IOstats = &zx.IOstats{} m.Dbg = zdebug ncfs.Debug = zdebug xfs, err := ncfs.New("cfs", m, t, rflag) if err != nil { return nil, nil, fmt.Errorf("cfs: %s", err) } st := &zx.IOstats{} xfs.IOstats = st if xaddr != "" { serve(xfs, xaddr) } if sflag { xfn := func() { st.Averages() dbg.Warn("%s iostats:\n%s\n", xfs.Name(), st) if fn != nil { fn() } } return xfs, xfn, nil } return xfs, fn, nil }
func main() { defer dbg.Exits("") os.Args[0] = "zx" port = "8002" opts.NewFlag("p", "port: tcp server port (8002 by default)", &port) wport = "9002" opts.NewFlag("w", "port: wax http server port", &wport) svc = "zx" opts.NewFlag("s", "srv: service name (zx by default)", &svc) addr = "*!*!zx" opts.NewFlag("a", "addr: service address (*!*!zx by default)", &addr) opts.NewFlag("v", "report users logged in/out (verbose)", &Verbose) opts.NewFlag("D", "debug", &Debug) opts.NewFlag("Z", "verbose debug", &Zdebug) opts.NewFlag("M", "debug mutexes", &cfs.DebugLocks) nopings := false opts.NewFlag("k", "do not use zx keep alives", &nopings) args, err := opts.Parse(os.Args) if err != nil { usage(err) } if len(args) == 0 { usage(errors.New("missing arguments")) } Debug = Debug || Zdebug auth.Debug = Debug cfs.Debug = Debug rfs.Verb = Verbose var trs []zx.Tree var ros = map[bool]string{false: "rw", true: "ro"} for i := 0; i < len(args); i++ { al := strings.Split(args[i], "!") if len(al) == 1 { al = append(al, al[0]) al[0] = path.Base(al[0]) } ronly := false caching := true if len(al) == 3 && strings.Contains(al[2], "ro") { ronly = true } if len(al) == 3 && strings.Contains(al[2], "nc") { caching = false } t, err := lfs.New(al[0], al[1], ronly && !caching) if err != nil { dbg.Warn("%s: %s", al[0], err) continue } t.ReadAttrs(true) t.SaveAttrs(caching) t.IOstats = &zx.IOstats{} fp, _ := filepath.Abs(al[1]) if caching { dbg.Warn("%s mfs + lfs %s caching", al[0], ros[ronly]) cache, err := mfs.New("mfs:" + al[0]) if err != nil { dbg.Warn("%s: mfs: %s", al[0], err) continue } cache.IOstats = &zx.IOstats{} cache.Dbg = Zdebug cache.WstatAll = true // cfs must be able to write it all x, err := cfs.New(al[0], cache, t, ronly) if err != nil { dbg.Warn("%s: cfs: %s", al[0], err) continue } x.IOstats = &zx.IOstats{} zxw[al[0]] = fp trs = append(trs, x) } else { dbg.Warn("%s lfs %s uncached", al[0], ros[ronly]) zxw[al[0]] = fp t.Dbg = Debug trs = append(trs, t) } } if len(trs) == 0 { dbg.Fatal("no trees to serve") } ds.DefSvc(svc, port) Vprintf("%s: serve %s...\n", os.Args[0], addr) cc, _, err := ds.Serve(os.Args[0], addr) if err != nil { dbg.Fatal("%s: serve: %s", os.Args[0], err) } go zxwax() for c := range cc { go func(c nchan.Conn) { ai, err := auth.AtServer(c, "", "zx", "finder") if err != nil && err != auth.ErrDisabled { Vprintf("%s: auth %s: %s\n", os.Args[0], c.Tag, err) close(c.In, err) close(c.Out, err) return } srv := rfs.Serve("rfs:"+c.Tag, c, ai, rfs.RW, trs...) if false { srv.Debug = Debug } srv.Pings = !nopings }(*c) } if err := cerror(cc); err != nil { dbg.Fatal("%s: serve: %s", os.Args[0], err) } }
func main() { defer dbg.Exits("") os.Args[0] = "zx" port = "8002" opts.NewFlag("p", "port: tcp server port", &port) wport = "9002" opts.NewFlag("w", "port: wax http server port", &wport) svc = "zx" opts.NewFlag("s", "srv: service name", &svc) addr = "*!*!zx" opts.NewFlag("a", "addr: service address", &addr) opts.NewFlag("D", "debug", &Debug) opts.NewFlag("Z", "verbose debug", &Zdebug) opts.NewFlag("k", "make cfg entries persist in the ns", &Persist) opts.NewFlag("N", "use new cfs", &New) args, err := opts.Parse(os.Args) if err != nil { usage(err) } if len(args) == 0 { usage(nil) } Debug = Debug || Zdebug auth.Debug = Debug ncfs.Debug = Debug cfs.Debug = Debug cfs.Cdebug = Zdebug cfs.Zdebug = Zdebug rfs.Verb = Verbose var trs []zx.Tree var ros = map[bool]string{false: "rw", true: "ro"} for i := 0; i < len(args); i++ { al := strings.Split(args[i], "!") if len(al) == 1 { al = append(al, al[0]) al[0] = path.Base(al[0]) } ronly := false caching := true if len(al) == 3 && strings.Contains(al[2], "ro") { ronly = true } if len(al) == 3 && strings.Contains(al[2], "nc") { caching = false } t, err := lfs.New(al[0], al[1], ronly && !caching) if err != nil { dbg.Warn("%s: %s", al[0], err) continue } t.ReadAttrs(true) t.SaveAttrs(caching) t.IOstats = &zx.IOstats{} fp, _ := filepath.Abs(al[1]) if New && caching { dbg.Warn("%s mfs + lfs %s caching", al[0], ros[ronly]) cache, err := mfs.New("mfs:" + al[0]) if err != nil { dbg.Warn("%s: mfs: %s", al[0], err) continue } cache.IOstats = &zx.IOstats{} cache.Dbg = Zdebug x, err := ncfs.New("cfs", cache, t, ronly) if err != nil { dbg.Warn("%s: cfs: %s", al[0], err) continue } x.IOstats = &zx.IOstats{} zxw[al[0]] = fp trs = append(trs, x) } else if !New && caching { dbg.Warn("%s old cfs + lfs %s caching", al[0], ros[ronly]) x, err := cfs.New("", t, ronly) if err != nil { dbg.Warn("%s: cfs: %s", al[0], err) continue } x.IOstats = &zx.IOstats{} zxw[al[0]] = fp trs = append(trs, x) } else { dbg.Warn("%s lfs %s uncached", al[0], ros[ronly]) zxw[al[0]] = fp t.Dbg = Debug trs = append(trs, t) } } if len(trs) == 0 { dbg.Fatal("no trees to serve") } ds.DefSvc(svc, port) Vprintf("%s: serve %s...\n", os.Args[0], addr) cc, _, err := ds.Serve(os.Args[0], addr) if err != nil { dbg.Fatal("%s: serve: %s", os.Args[0], err) } go zxwax() for c := range cc { go func(c nchan.Conn) { ai, err := auth.AtServer(c, "", "zx", "finder") if err != nil && err != auth.ErrDisabled { Vprintf("%s: auth %s: %s\n", os.Args[0], c.Tag, err) close(c.In, err) close(c.Out, err) return } srv := rfs.Serve("rfs:"+c.Tag, c, ai, rfs.RW, trs...) if false { srv.Debug = Debug } }(*c) } if err := cerror(cc); err != nil { dbg.Fatal("%s: serve: %s", os.Args[0], err) } }
func mkfs(addr string, quiet bool) (zx.Tree, func(), error) { if len(addr) == 0 { dbg.Warn("missing address") opts.Usage() dbg.Fatal("usage") } dbp := &fs.Debug var m, fs zx.RWTree var fsst *zx.IOstats var err error var lflags, flags *zx.Flags if _, err = os.Stat(addr); err == nil { fs, flags, fsst, err = mklfs(addr) } else { fs, flags, fsst, err = mkrfs(addr) } if err != nil { return nil, nil, err } switch { case nocache: dbg.Warn("%s: uncached", addr) if xaddr != "" { rfs.Server(fs, xaddr) } fn := func() {} if sflag { fn = func() { fsst.Averages() dbg.Warn("%s iostats:\n%s\n", fs.Name(), fsst) } } return fs, fn, nil case lfscache != "": dbg.Warn("%s: lfs cache %s", addr, lfscache) m, lflags, err = dcache() case mlfscache != "": dbg.Warn("%s: mdfs cache %s", addr, mlfscache) m, lflags, err = mdcache() default: dbg.Warn("%s: mfs cache", addr) m, lflags, err = mcache() } if err != nil { return nil, nil, err } cfs.Debug = zxdebug xfs, err := cfs.New("cfs", m, fs, rflag) if err != nil { return nil, nil, fmt.Errorf("cfs: %s", err) } xfs.Flags.Add("rdebug", &flags.Dbg) if lflags != nil { xfs.Flags.Add("ldebug", &lflags.Dbg) } xfs.Flags.Add("fdebug", &zxfs.Debug) xfs.Flags.Add("vdebug", dbp) xfs.Flags.Set("verbsync", !quiet) st := &zx.IOstats{} xfs.IOstats = st if xaddr != "" { rfs.Server(xfs, xaddr) } fn := func() {} if sflag { fn = func() { st.Averages() dbg.Warn("%s iostats:\n%s\n", xfs.Name(), st) fsst.Averages() dbg.Warn("%s iostats:\n%s\n", fs.Name(), fsst) } } return xfs, fn, nil }