From 60194645507aac2448614f1cbf5a427f165bd14c Mon Sep 17 00:00:00 2001 From: Kirill Smelkov <kirr@nexedi.com> Date: Mon, 1 Jul 2019 11:59:18 +0300 Subject: [PATCH] . --- wcfs/wcfs.go | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/wcfs/wcfs.go b/wcfs/wcfs.go index 9ce596a..d30354e 100644 --- a/wcfs/wcfs.go +++ b/wcfs/wcfs.go @@ -692,15 +692,17 @@ func traceZWatch(format string, argv ...interface{}) { // zwatcher watches for ZODB changes. // // see "4) when we receive an invalidation message from ZODB ..." +/* func (root *Root) zwatcher(ctx context.Context, zwatchq chan zodb.Event) { err := root._zwatcher(ctx, zwatchq) if err != nil { panic(err) // XXX -> wg.Wait in main } } +*/ -func (root *Root) _zwatcher(ctx context.Context, zwatchq chan zodb.Event) (err error) { - defer xerr.Contextf(&err, "zwatch %s", root.zstor.URL()) +func (root *Root) zwatcher(ctx context.Context, zwatchq chan zodb.Event) (err error) { + defer xerr.Contextf(&err, "zwatch %s", root.zstor.URL()) // XXX err ctx recheck // XXX error -> always EIO for data operations // XXX unmount -> stop traceZWatch(">>>") @@ -2163,7 +2165,7 @@ func _main() (err error) { NoPool: true, }) if err != nil { - log.Fatal(err) + return err } zhead.Cache().Lock() zhead.Cache().SetControl(&zodbCacheControl{}) @@ -2220,7 +2222,7 @@ func _main() (err error) { fssrv, fsconn, err := mount(mntpt, root, opts) if err != nil { - log.Fatal(err) + return err } groot = root // FIXME temp workaround (see ^^^) gfsconn = fsconn // FIXME ----//---- @@ -2231,7 +2233,7 @@ func _main() (err error) { kfuse := fmt.Sprintf("kernel FUSE (API %d.%d)", kinit.Major, kinit.Minor) supports := kinit.SupportsNotify if !(supports(fuse.NOTIFY_STORE_CACHE) && supports(fuse.NOTIFY_RETRIEVE_CACHE)) { - log.Fatalf("%s does not support pagecache control", kfuse) + return fmt.Errorf("%s does not support pagecache control", kfuse) } // make a bold warning if kernel does not support explicit cache invalidation // (patch sent upstream; see notes.txt -> "Notes on OS pagecache control") @@ -2265,32 +2267,39 @@ func _main() (err error) { fsNode: newFSNode(fSticky), }) - // XXX place = ok? - // XXX ctx = ok? XXX -> joined ctx for fs.Serve + zwatcher ? - // XXX wait for zwatcher shutdown + log from it error - go root.zwatcher(ctx, zwatchq) - // TODO handle autoexit // (exit when kernel forgets all our inodes - wcfs.py keeps .wcfs/zurl // opened, so when all inodes has been forgotten - we know all wcfs.py clients exited) _ = autoexit - // serve client requests. + // spawn filesystem server. // // use `go serve` + `waitMount` not just `serve` - because waitMount // cares to disable OS calling poll on us. // ( if we don't disable polling - fs serving can get stuck - see // https://github.com/hanwen/go-fuse/commit/4f10e248eb for details ) - done := make(chan struct{}) + serveCtx, serveCancel := context.WithCancel(context.Background()) go func () { + defer serveCancel() fssrv.Serve() - close(done) }() err = fssrv.WaitMount() if err != nil { - log.Fatal(err) // XXX err ctx? + return err // XXX err ctx? + } + + // filesystem server is serving requests. + // run zwatcher and wait for it to complete. + // zwatcher completes either normally - due to filesystem unmount, or fails. + // if zwatcher fails - switch filesystem to return EIO instead of stale data. + err = root.zwatcher(serveCtx, zwatchq) + if errors.Cause(err) != context.Canceled { + log.Error(err) + log.Errorf("-> switching filesystem to EIO mode") + // XXX switch fs to EIO mode } - <-done + // wait for unmount + <-serveCtx.Done() return nil } -- 2.30.9