diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-11-07 16:01:00 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-11-07 16:50:40 +0000 |
| commit | 6410b21bc162fd5f9527bda7484828c53cd872d0 (patch) | |
| tree | b628ceee8e459fa8e62ab492ba38e577b5d777ac | |
| parent | 069a4a6eb9923b8553bcbc4dd2d75a528da14453 (diff) | |
pkg/manager: set more http fields before calling Serve
Pools and ReproLoop and always created on start,
so there is no need to support lazy set for them.
It only complicates code and makes it harder to reason about.
Also introduce vm.Dispatcher as an alias to dispatcher.Pool,
as it's the only specialization we use in the project.
| -rw-r--r-- | pkg/manager/http.go | 36 | ||||
| -rw-r--r-- | pkg/repro/repro.go | 4 | ||||
| -rw-r--r-- | pkg/repro/strace.go | 3 | ||||
| -rw-r--r-- | syz-manager/manager.go | 10 | ||||
| -rw-r--r-- | tools/syz-diff/diff.go | 10 | ||||
| -rw-r--r-- | vm/vm.go | 4 |
6 files changed, 31 insertions, 36 deletions
diff --git a/pkg/manager/http.go b/pkg/manager/http.go index 38a9b9432..41bd59db4 100644 --- a/pkg/manager/http.go +++ b/pkg/manager/http.go @@ -18,7 +18,6 @@ import ( "sort" "strconv" "strings" - "sync" "sync/atomic" "time" @@ -46,18 +45,19 @@ type CoverageInfo struct { } type HTTPServer struct { - // To be set once. + // To be set before calling Serve. Cfg *mgrconfig.Config StartTime time.Time CrashStore *CrashStore DiffStore *DiffFuzzerStore + ReproLoop *ReproLoop + Pool *vm.Dispatcher + Pools map[string]*vm.Dispatcher - // Set dynamically. + // Can be set dynamically after calling Serve. Corpus atomic.Pointer[corpus.Corpus] Fuzzer atomic.Pointer[fuzzer.Fuzzer] Cover atomic.Pointer[CoverageInfo] - ReproLoop atomic.Pointer[ReproLoop] - Pools sync.Map // string => dispatcher.Pool[*vm.Instance] EnabledSyscalls atomic.Value // map[*prog.Syscall]bool // Internal state. @@ -65,6 +65,9 @@ type HTTPServer struct { } func (serv *HTTPServer) Serve() { + if serv.Pool != nil { + serv.Pools = map[string]*vm.Dispatcher{"": serv.Pool} + } handle := func(pattern string, handler func(http.ResponseWriter, *http.Request)) { http.Handle(pattern, handlers.CompressHandler(http.HandlerFunc(handler))) } @@ -208,15 +211,12 @@ func (serv *HTTPServer) httpStats(w http.ResponseWriter, r *http.Request) { executeTemplate(w, pages.StatsTemplate, stat.RenderGraphs()) } -const DefaultPool = "" - func (serv *HTTPServer) httpVMs(w http.ResponseWriter, r *http.Request) { - poolObj, ok := serv.Pools.Load(r.FormValue("pool")) - if !ok { + pool := serv.Pools[r.FormValue("pool")] + if pool == nil { http.Error(w, "no such VM pool is known (yet)", http.StatusInternalServerError) return } - pool := poolObj.(*dispatcher.Pool[*vm.Instance]) data := &UIVMData{ Name: serv.Cfg.Name, } @@ -254,12 +254,11 @@ func (serv *HTTPServer) httpVMs(w http.ResponseWriter, r *http.Request) { } func (serv *HTTPServer) httpVM(w http.ResponseWriter, r *http.Request) { - poolObj, ok := serv.Pools.Load(r.FormValue("pool")) - if !ok { + pool := serv.Pools[r.FormValue("pool")] + if pool == nil { http.Error(w, "no such VM pool is known (yet)", http.StatusInternalServerError) return } - pool := poolObj.(*dispatcher.Pool[*vm.Instance]) w.Header().Set("Content-Type", ctTextPlain) id, err := strconv.Atoi(r.FormValue("id")) @@ -760,7 +759,7 @@ func (serv *HTTPServer) collectDiffCrashes() (patchedOnly, both, inProgress *UID } func (serv *HTTPServer) allDiffCrashes() []UIDiffBug { - repros := serv.nowReproducing() + repros := serv.ReproLoop.Reproducing() var list []UIDiffBug for _, bug := range serv.DiffStore.List() { list = append(list, UIDiffBug{ @@ -779,19 +778,12 @@ func (serv *HTTPServer) allDiffCrashes() []UIDiffBug { return list } -func (serv *HTTPServer) nowReproducing() map[string]bool { - if reproLoop := serv.ReproLoop.Load(); reproLoop != nil { - return reproLoop.Reproducing() - } - return nil -} - func (serv *HTTPServer) collectCrashes(workdir string) ([]UICrashType, error) { list, err := serv.CrashStore.BugList() if err != nil { return nil, err } - repros := serv.nowReproducing() + repros := serv.ReproLoop.Reproducing() var ret []UICrashType for _, info := range list { ret = append(ret, makeUICrashType(info, serv.StartTime, repros)) diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go index 65e0f6d2b..dae7a3cd4 100644 --- a/pkg/repro/repro.go +++ b/pkg/repro/repro.go @@ -74,7 +74,7 @@ type execInterface interface { var Fast = &struct{}{} func Run(crashLog []byte, cfg *mgrconfig.Config, features flatrpc.Feature, reporter *report.Reporter, - pool *dispatcher.Pool[*vm.Instance], opts ...any) (*Result, *Stats, error) { + pool *vm.Dispatcher, opts ...any) (*Result, *Stats, error) { exec := &poolWrapper{ cfg: cfg, reporter: reporter, @@ -747,7 +747,7 @@ func (ctx *reproContext) bisectProgs(progs []*prog.LogEntry, pred func([]*prog.L type poolWrapper struct { cfg *mgrconfig.Config reporter *report.Reporter - pool *dispatcher.Pool[*vm.Instance] + pool *vm.Dispatcher logf func(level int, format string, args ...interface{}) } diff --git a/pkg/repro/strace.go b/pkg/repro/strace.go index 72ecc0954..9aaeb6498 100644 --- a/pkg/repro/strace.go +++ b/pkg/repro/strace.go @@ -25,8 +25,7 @@ const ( straceOutputLogSize = 2048 << 10 ) -func RunStrace(result *Result, cfg *mgrconfig.Config, reporter *report.Reporter, - pool *dispatcher.Pool[*vm.Instance]) *StraceResult { +func RunStrace(result *Result, cfg *mgrconfig.Config, reporter *report.Reporter, pool *vm.Dispatcher) *StraceResult { if cfg.StraceBin == "" { return straceFailed(fmt.Errorf("strace binary is not set in the config")) } diff --git a/syz-manager/manager.go b/syz-manager/manager.go index 922639407..9318bf8b2 100644 --- a/syz-manager/manager.go +++ b/syz-manager/manager.go @@ -73,7 +73,7 @@ type Manager struct { cfg *mgrconfig.Config mode Mode vmPool *vm.Pool - pool *dispatcher.Pool[*vm.Instance] + pool *vm.Dispatcher target *prog.Target sysTarget *targets.Target reporter *report.Reporter @@ -242,8 +242,6 @@ func RunManager(mode Mode, cfg *mgrconfig.Config) { } else { close(mgr.corpusPreload) } - go mgr.http.Serve() - go mgr.trackUsedFiles() // Create RPC server for fuzzers. mgr.servStats = rpcserver.NewStats() @@ -294,11 +292,13 @@ func RunManager(mode Mode, cfg *mgrconfig.Config) { return } mgr.pool = vm.NewDispatcher(mgr.vmPool, mgr.fuzzerInstance) - mgr.http.Pools.Store(manager.DefaultPool, mgr.pool) + mgr.http.Pool = mgr.pool mgr.reproLoop = manager.NewReproLoop(mgr, mgr.vmPool.Count()-mgr.cfg.FuzzingVMs, mgr.cfg.DashboardOnlyRepro) - mgr.http.ReproLoop.Store(mgr.reproLoop) + mgr.http.ReproLoop = mgr.reproLoop ctx := vm.ShutdownCtx() + go mgr.http.Serve() + go mgr.trackUsedFiles() go mgr.processFuzzingResults(ctx) mgr.pool.Loop(ctx) } diff --git a/tools/syz-diff/diff.go b/tools/syz-diff/diff.go index 6a6a0991d..c3da6c8ec 100644 --- a/tools/syz-diff/diff.go +++ b/tools/syz-diff/diff.go @@ -93,8 +93,10 @@ func main() { DiffStore: store, }, } - diffCtx.http.Pools.Store(new.name, new.pool) - diffCtx.http.Pools.Store(base.name, base.pool) + diffCtx.http.Pools = map[string]*vm.Dispatcher{ + new.name: new.pool, + base.name: base.pool, + } new.http = diffCtx.http diffCtx.Loop(ctx) @@ -114,7 +116,7 @@ type diffContext struct { func (dc *diffContext) Loop(ctx context.Context) { reproLoop := manager.NewReproLoop(dc, dc.new.pool.Total()-dc.new.cfg.FuzzingVMs, false) - dc.http.ReproLoop.Store(reproLoop) + dc.http.ReproLoop = reproLoop go func() { // Let both base and patched instances somewhat progress in fuzzing before we take // VMs away for bug reproduction. @@ -235,7 +237,7 @@ type kernelContext struct { serv rpcserver.Server servStats rpcserver.Stats crashes chan *report.Report - pool *dispatcher.Pool[*vm.Instance] + pool *vm.Dispatcher features flatrpc.Feature candidates chan []fuzzer.Candidate @@ -332,7 +332,9 @@ func (inst *Instance) Close() error { return err } -func NewDispatcher(pool *Pool, def dispatcher.Runner[*Instance]) *dispatcher.Pool[*Instance] { +type Dispatcher = dispatcher.Pool[*Instance] + +func NewDispatcher(pool *Pool, def dispatcher.Runner[*Instance]) *Dispatcher { return dispatcher.NewPool(pool.Count(), pool.Create, def) } |
