func cache(t zx.Tree, fn func()) (zx.Tree, func(), error) { cfs.Debug = zdebug cfs.Cdebug = zdebug xfs, err := cfs.New("", 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", &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) } }