aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-11-07 16:01:00 +0100
committerDmitry Vyukov <dvyukov@google.com>2024-11-07 16:50:40 +0000
commit6410b21bc162fd5f9527bda7484828c53cd872d0 (patch)
treeb628ceee8e459fa8e62ab492ba38e577b5d777ac
parent069a4a6eb9923b8553bcbc4dd2d75a528da14453 (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.go36
-rw-r--r--pkg/repro/repro.go4
-rw-r--r--pkg/repro/strace.go3
-rw-r--r--syz-manager/manager.go10
-rw-r--r--tools/syz-diff/diff.go10
-rw-r--r--vm/vm.go4
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
diff --git a/vm/vm.go b/vm/vm.go
index d2165a276..27e6f319e 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -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)
}