Skip to content

Commit

Permalink
vm: export VM output metric
Browse files Browse the repository at this point in the history
VM output we receive on the host is effectively equivalent to RPC recv metric.
If we stop printing programs in the fuzzer, traffic will move from output to RPC.
It will be useful to see this change via metrics.
  • Loading branch information
dvyukov committed Apr 15, 2024
1 parent ff69821 commit e634f46
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 28 deletions.
8 changes: 2 additions & 6 deletions pkg/rpctype/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,14 @@ func NewRPCServer(addr, name string, receiver interface{}, useCompression bool)
if err := s.RegisterName(name, receiver); err != nil {
return nil, err
}
formatMB := func(v int, period time.Duration) string {
const KB, MB = 1 << 10, 1 << 20
return fmt.Sprintf("%v MB (%v kb/sec)", (v+MB/2)/MB, (v+KB/2)/KB/int(period/time.Second))
}
serv := &RPCServer{
ln: ln,
s: s,
useCompression: useCompression,
statSent: stats.Create("rpc sent", "Uncompressed outbound RPC traffic",
stats.Graph("RPC traffic"), stats.Rate{}, formatMB),
stats.Graph("traffic"), stats.Rate{}, stats.FormatMB),
statRecv: stats.Create("rpc recv", "Uncompressed inbound RPC traffic",
stats.Graph("RPC traffic"), stats.Rate{}, formatMB),
stats.Graph("traffic"), stats.Rate{}, stats.FormatMB),
}
return serv, nil
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/stats/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ func LenOf(containerPtr any, mu *sync.RWMutex) func() int {
}
}

func FormatMB(v int, period time.Duration) string {
const KB, MB = 1 << 10, 1 << 20
return fmt.Sprintf("%v MB (%v kb/sec)", (v+MB/2)/MB, (v+KB/2)/KB/int(period/time.Second))
}

// Addittionally a custom 'func() int' can be passed to read the metric value from the function.
// and 'func(int, time.Duration) string' can be passed for custom formatting of the metric value.

Expand Down
47 changes: 25 additions & 22 deletions vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/google/syzkaller/pkg/mgrconfig"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/pkg/report"
"github.com/google/syzkaller/pkg/stats"
"github.com/google/syzkaller/sys/targets"
"github.com/google/syzkaller/vm/vmimpl"

Expand All @@ -39,21 +40,21 @@ import (
)

type Pool struct {
impl vmimpl.Pool
workdir string
template string
timeouts targets.Timeouts
activeCount int32
hostFuzzer bool
impl vmimpl.Pool
workdir string
template string
timeouts targets.Timeouts
activeCount int32
hostFuzzer bool
statOutputReceived *stats.Val
}

type Instance struct {
impl vmimpl.Instance
workdir string
timeouts targets.Timeouts
index int
onClose func()
hostFuzzer bool
pool *Pool
impl vmimpl.Instance
workdir string
index int
onClose func()
}

var (
Expand Down Expand Up @@ -126,6 +127,8 @@ func Create(cfg *mgrconfig.Config, debug bool) (*Pool, error) {
template: cfg.WorkdirTemplate,
timeouts: cfg.Timeouts,
hostFuzzer: cfg.SysTarget.HostFuzzer,
statOutputReceived: stats.Create("vm output", "Bytes of VM console output received",
stats.Graph("traffic"), stats.Rate{}, stats.FormatMB),
}, nil
}

Expand Down Expand Up @@ -153,12 +156,11 @@ func (pool *Pool) Create(index int) (*Instance, error) {
}
atomic.AddInt32(&pool.activeCount, 1)
return &Instance{
impl: impl,
workdir: workdir,
timeouts: pool.timeouts,
index: index,
onClose: func() { atomic.AddInt32(&pool.activeCount, -1) },
hostFuzzer: pool.hostFuzzer,
pool: pool,
impl: impl,
workdir: workdir,
index: index,
onClose: func() { atomic.AddInt32(&pool.activeCount, -1) },
}, nil
}

Expand Down Expand Up @@ -251,7 +253,7 @@ func (inst *Instance) Info() ([]byte, error) {
}

func (inst *Instance) PprofPort() int {
if inst.hostFuzzer {
if inst.pool.hostFuzzer {
// In the fuzzing on host mode, fuzzers are always on the same network.
// Don't set up pprof endpoints in this case.
return 0
Expand Down Expand Up @@ -289,7 +291,7 @@ type monitor struct {
}

func (mon *monitor) monitorExecution() *report.Report {
ticker := time.NewTicker(tickerPeriod * mon.inst.timeouts.Scale)
ticker := time.NewTicker(tickerPeriod * mon.inst.pool.timeouts.Scale)
defer ticker.Stop()
for {
select {
Expand Down Expand Up @@ -322,6 +324,7 @@ func (mon *monitor) monitorExecution() *report.Report {
mon.outc = nil
continue
}
mon.inst.pool.statOutputReceived.Add(len(out))
if rep := mon.appendOutput(out); rep != nil {
return rep
}
Expand All @@ -332,7 +335,7 @@ func (mon *monitor) monitorExecution() *report.Report {
case <-ticker.C:
// Detect both "no output whatsoever" and "kernel episodically prints
// something to console, but fuzzer is not actually executing programs".
if time.Since(mon.lastExecuteTime) > mon.inst.timeouts.NoOutput {
if time.Since(mon.lastExecuteTime) > mon.inst.pool.timeouts.NoOutput {
return mon.extractError(noOutputCrash)
}
case <-Shutdown:
Expand Down Expand Up @@ -432,7 +435,7 @@ func (mon *monitor) createReport(defaultError string) *report.Report {
}

func (mon *monitor) waitForOutput() {
timer := time.NewTimer(waitForOutputTimeout * mon.inst.timeouts.Scale)
timer := time.NewTimer(waitForOutputTimeout * mon.inst.pool.timeouts.Scale)
defer timer.Stop()
for {
select {
Expand Down

0 comments on commit e634f46

Please sign in to comment.