github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/fuzzer/queue/retry.go (about) 1 // Copyright 2024 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 package queue 5 6 import ( 7 "fmt" 8 ) 9 10 type retryer struct { 11 pq *PlainQueue 12 base Source 13 } 14 15 // Retry adds a layer that resends results with Status=Restarted. 16 func Retry(base Source) Source { 17 return &retryer{ 18 base: base, 19 pq: Plain(), 20 } 21 } 22 23 func (r *retryer) Next() *Request { 24 req := r.pq.tryNext() 25 if req == nil { 26 req = r.base.Next() 27 } 28 if req != nil { 29 req.OnDone(r.done) 30 } 31 return req 32 } 33 34 func (r *retryer) done(req *Request, res *Result) bool { 35 switch res.Status { 36 case Success, ExecFailure, Hanged: 37 return true 38 case Restarted: 39 // The input was on a restarted VM. 40 r.pq.Submit(req) 41 return false 42 case Crashed: 43 // Retry important requests from crashed VMs once. 44 if req.Important && !req.onceCrashed { 45 req.onceCrashed = true 46 r.pq.Submit(req) 47 return false 48 } 49 return true 50 default: 51 panic(fmt.Sprintf("unhandled status %v", res.Status)) 52 } 53 }