diff options
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/flatrpc/conn_test.go | 2 | ||||
| -rw-r--r-- | pkg/flatrpc/flatrpc.fbs | 17 | ||||
| -rw-r--r-- | pkg/flatrpc/flatrpc.go | 207 | ||||
| -rw-r--r-- | pkg/flatrpc/flatrpc.h | 174 | ||||
| -rw-r--r-- | pkg/fuzzer/queue/queue.go | 67 | ||||
| -rw-r--r-- | pkg/fuzzer/queue/queue_test.go | 7 | ||||
| -rw-r--r-- | pkg/ifaceprobe/ifaceprobe.go | 179 | ||||
| -rw-r--r-- | pkg/rpcserver/local.go | 3 | ||||
| -rw-r--r-- | pkg/rpcserver/mocks/Manager.go | 10 | ||||
| -rw-r--r-- | pkg/rpcserver/rpcserver.go | 25 | ||||
| -rw-r--r-- | pkg/rpcserver/runner.go | 31 | ||||
| -rw-r--r-- | pkg/runtest/run.go | 5 | ||||
| -rw-r--r-- | pkg/vminfo/syscalls.go | 36 | ||||
| -rw-r--r-- | pkg/vminfo/vminfo.go | 3 | ||||
| -rw-r--r-- | pkg/vminfo/vminfo_test.go | 27 |
15 files changed, 450 insertions, 343 deletions
diff --git a/pkg/flatrpc/conn_test.go b/pkg/flatrpc/conn_test.go index 3ab83996e..132fd1cdd 100644 --- a/pkg/flatrpc/conn_test.go +++ b/pkg/flatrpc/conn_test.go @@ -28,7 +28,6 @@ func TestConn(t *testing.T) { RaceFrames: []string{"bar", "baz"}, Features: FeatureCoverage | FeatureLeak, Files: []string{"file1"}, - Globs: []string{"glob1"}, } executorMsg := &ExecutorMessage{ Msg: &ExecutorMessages{ @@ -102,7 +101,6 @@ func BenchmarkConn(b *testing.B) { RaceFrames: []string{"bar", "baz"}, Features: FeatureCoverage | FeatureLeak, Files: []string{"file1"}, - Globs: []string{"glob1"}, } done := make(chan bool) diff --git a/pkg/flatrpc/flatrpc.fbs b/pkg/flatrpc/flatrpc.fbs index 0bd32b743..6d2307d6a 100644 --- a/pkg/flatrpc/flatrpc.fbs +++ b/pkg/flatrpc/flatrpc.fbs @@ -57,14 +57,12 @@ table ConnectReplyRaw { features :Feature; // Fuzzer reads these files inside of the VM and returns contents in InfoRequest.files. files :[string]; - globs :[string]; } table InfoRequestRaw { error :string; features :[FeatureInfoRaw]; files :[FileInfoRaw]; - globs :[GlobInfoRaw]; } table InfoReplyRaw { @@ -112,10 +110,16 @@ table ExecutorMessageRaw { msg :ExecutorMessagesRaw; } +enum RequestType : uint64 { + // Normal test program request (data contains serialized prog.Prog). + Program, + // Binary test program (data contains compiled executable binary). + Binary, + // Request for file glob expansion (data contains the glob pattern). + Glob, +} + enum RequestFlag : uint64 (bit_flags) { - // If set, prog_data contains compiled executable binary - // that needs to be written to disk and executed. - IsBinary, // If set, collect program output and return in output field. ReturnOutput, // If set, don't fail on program failures, instead return the error in error field. @@ -163,9 +167,10 @@ struct ExecOptsRaw { // Request to execute a test program. table ExecRequestRaw { id :int64; + type :RequestType; // Bitmask of procs to avoid when executing this request, if possible. avoid :uint64; - prog_data :[uint8]; + data :[uint8]; exec_opts :ExecOptsRaw; flags :RequestFlag; // Return all signal for these calls. diff --git a/pkg/flatrpc/flatrpc.go b/pkg/flatrpc/flatrpc.go index 8445cde2d..fd5b4f614 100644 --- a/pkg/flatrpc/flatrpc.go +++ b/pkg/flatrpc/flatrpc.go @@ -257,22 +257,46 @@ func (rcv ExecutorMessagesRaw) UnPack(table flatbuffers.Table) *ExecutorMessages return nil } +type RequestType uint64 + +const ( + RequestTypeProgram RequestType = 0 + RequestTypeBinary RequestType = 1 + RequestTypeGlob RequestType = 2 +) + +var EnumNamesRequestType = map[RequestType]string{ + RequestTypeProgram: "Program", + RequestTypeBinary: "Binary", + RequestTypeGlob: "Glob", +} + +var EnumValuesRequestType = map[string]RequestType{ + "Program": RequestTypeProgram, + "Binary": RequestTypeBinary, + "Glob": RequestTypeGlob, +} + +func (v RequestType) String() string { + if s, ok := EnumNamesRequestType[v]; ok { + return s + } + return "RequestType(" + strconv.FormatInt(int64(v), 10) + ")" +} + type RequestFlag uint64 const ( - RequestFlagIsBinary RequestFlag = 1 - RequestFlagReturnOutput RequestFlag = 2 - RequestFlagReturnError RequestFlag = 4 + RequestFlagReturnOutput RequestFlag = 1 + RequestFlagReturnError RequestFlag = 2 ) var EnumNamesRequestFlag = map[RequestFlag]string{ - RequestFlagIsBinary: "IsBinary", RequestFlagReturnOutput: "ReturnOutput", RequestFlagReturnError: "ReturnError", } var EnumValuesRequestFlag = map[string]RequestFlag{ - "IsBinary": RequestFlagIsBinary, "ReturnOutput": RequestFlagReturnOutput, "ReturnError": RequestFlagReturnError, } @@ -594,7 +618,6 @@ type ConnectReplyRawT struct { RaceFrames []string `json:"race_frames"` Features Feature `json:"features"` Files []string `json:"files"` - Globs []string `json:"globs"` } func (t *ConnectReplyRawT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { @@ -640,19 +663,6 @@ func (t *ConnectReplyRawT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffse } filesOffset = builder.EndVector(filesLength) } - globsOffset := flatbuffers.UOffsetT(0) - if t.Globs != nil { - globsLength := len(t.Globs) - globsOffsets := make([]flatbuffers.UOffsetT, globsLength) - for j := 0; j < globsLength; j++ { - globsOffsets[j] = builder.CreateString(t.Globs[j]) - } - ConnectReplyRawStartGlobsVector(builder, globsLength) - for j := globsLength - 1; j >= 0; j-- { - builder.PrependUOffsetT(globsOffsets[j]) - } - globsOffset = builder.EndVector(globsLength) - } ConnectReplyRawStart(builder) ConnectReplyRawAddDebug(builder, t.Debug) ConnectReplyRawAddCover(builder, t.Cover) @@ -666,7 +676,6 @@ func (t *ConnectReplyRawT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffse ConnectReplyRawAddRaceFrames(builder, raceFramesOffset) ConnectReplyRawAddFeatures(builder, t.Features) ConnectReplyRawAddFiles(builder, filesOffset) - ConnectReplyRawAddGlobs(builder, globsOffset) return ConnectReplyRawEnd(builder) } @@ -695,11 +704,6 @@ func (rcv *ConnectReplyRaw) UnPackTo(t *ConnectReplyRawT) { for j := 0; j < filesLength; j++ { t.Files[j] = string(rcv.Files(j)) } - globsLength := rcv.GlobsLength() - t.Globs = make([]string, globsLength) - for j := 0; j < globsLength; j++ { - t.Globs[j] = string(rcv.Globs(j)) - } } func (rcv *ConnectReplyRaw) UnPack() *ConnectReplyRawT { @@ -897,25 +901,8 @@ func (rcv *ConnectReplyRaw) FilesLength() int { return 0 } -func (rcv *ConnectReplyRaw) Globs(j int) []byte { - o := flatbuffers.UOffsetT(rcv._tab.Offset(28)) - if o != 0 { - a := rcv._tab.Vector(o) - return rcv._tab.ByteVector(a + flatbuffers.UOffsetT(j*4)) - } - return nil -} - -func (rcv *ConnectReplyRaw) GlobsLength() int { - o := flatbuffers.UOffsetT(rcv._tab.Offset(28)) - if o != 0 { - return rcv._tab.VectorLen(o) - } - return 0 -} - func ConnectReplyRawStart(builder *flatbuffers.Builder) { - builder.StartObject(13) + builder.StartObject(12) } func ConnectReplyRawAddDebug(builder *flatbuffers.Builder, debug bool) { builder.PrependBoolSlot(0, debug, false) @@ -962,12 +949,6 @@ func ConnectReplyRawAddFiles(builder *flatbuffers.Builder, files flatbuffers.UOf func ConnectReplyRawStartFilesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems, 4) } -func ConnectReplyRawAddGlobs(builder *flatbuffers.Builder, globs flatbuffers.UOffsetT) { - builder.PrependUOffsetTSlot(12, flatbuffers.UOffsetT(globs), 0) -} -func ConnectReplyRawStartGlobsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { - return builder.StartVector(4, numElems, 4) -} func ConnectReplyRawEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() } @@ -976,7 +957,6 @@ type InfoRequestRawT struct { Error string `json:"error"` Features []*FeatureInfoRawT `json:"features"` Files []*FileInfoRawT `json:"files"` - Globs []*GlobInfoRawT `json:"globs"` } func (t *InfoRequestRawT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { @@ -1010,24 +990,10 @@ func (t *InfoRequestRawT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffset } filesOffset = builder.EndVector(filesLength) } - globsOffset := flatbuffers.UOffsetT(0) - if t.Globs != nil { - globsLength := len(t.Globs) - globsOffsets := make([]flatbuffers.UOffsetT, globsLength) - for j := 0; j < globsLength; j++ { - globsOffsets[j] = t.Globs[j].Pack(builder) - } - InfoRequestRawStartGlobsVector(builder, globsLength) - for j := globsLength - 1; j >= 0; j-- { - builder.PrependUOffsetT(globsOffsets[j]) - } - globsOffset = builder.EndVector(globsLength) - } InfoRequestRawStart(builder) InfoRequestRawAddError(builder, errorOffset) InfoRequestRawAddFeatures(builder, featuresOffset) InfoRequestRawAddFiles(builder, filesOffset) - InfoRequestRawAddGlobs(builder, globsOffset) return InfoRequestRawEnd(builder) } @@ -1047,13 +1013,6 @@ func (rcv *InfoRequestRaw) UnPackTo(t *InfoRequestRawT) { rcv.Files(&x, j) t.Files[j] = x.UnPack() } - globsLength := rcv.GlobsLength() - t.Globs = make([]*GlobInfoRawT, globsLength) - for j := 0; j < globsLength; j++ { - x := GlobInfoRaw{} - rcv.Globs(&x, j) - t.Globs[j] = x.UnPack() - } } func (rcv *InfoRequestRaw) UnPack() *InfoRequestRawT { @@ -1140,28 +1099,8 @@ func (rcv *InfoRequestRaw) FilesLength() int { return 0 } -func (rcv *InfoRequestRaw) Globs(obj *GlobInfoRaw, j int) bool { - o := flatbuffers.UOffsetT(rcv._tab.Offset(10)) - if o != 0 { - x := rcv._tab.Vector(o) - x += flatbuffers.UOffsetT(j) * 4 - x = rcv._tab.Indirect(x) - obj.Init(rcv._tab.Bytes, x) - return true - } - return false -} - -func (rcv *InfoRequestRaw) GlobsLength() int { - o := flatbuffers.UOffsetT(rcv._tab.Offset(10)) - if o != 0 { - return rcv._tab.VectorLen(o) - } - return 0 -} - func InfoRequestRawStart(builder *flatbuffers.Builder) { - builder.StartObject(4) + builder.StartObject(3) } func InfoRequestRawAddError(builder *flatbuffers.Builder, error flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(error), 0) @@ -1178,12 +1117,6 @@ func InfoRequestRawAddFiles(builder *flatbuffers.Builder, files flatbuffers.UOff func InfoRequestRawStartFilesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems, 4) } -func InfoRequestRawAddGlobs(builder *flatbuffers.Builder, globs flatbuffers.UOffsetT) { - builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(globs), 0) -} -func InfoRequestRawStartGlobsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { - return builder.StartVector(4, numElems, 4) -} func InfoRequestRawEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() } @@ -1929,8 +1862,9 @@ func CreateExecOptsRaw(builder *flatbuffers.Builder, envFlags ExecEnv, execFlags type ExecRequestRawT struct { Id int64 `json:"id"` + Type RequestType `json:"type"` Avoid uint64 `json:"avoid"` - ProgData []byte `json:"prog_data"` + Data []byte `json:"data"` ExecOpts *ExecOptsRawT `json:"exec_opts"` Flags RequestFlag `json:"flags"` AllSignal []int32 `json:"all_signal"` @@ -1940,9 +1874,9 @@ func (t *ExecRequestRawT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffset if t == nil { return 0 } - progDataOffset := flatbuffers.UOffsetT(0) - if t.ProgData != nil { - progDataOffset = builder.CreateByteString(t.ProgData) + dataOffset := flatbuffers.UOffsetT(0) + if t.Data != nil { + dataOffset = builder.CreateByteString(t.Data) } allSignalOffset := flatbuffers.UOffsetT(0) if t.AllSignal != nil { @@ -1955,8 +1889,9 @@ func (t *ExecRequestRawT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffset } ExecRequestRawStart(builder) ExecRequestRawAddId(builder, t.Id) + ExecRequestRawAddType(builder, t.Type) ExecRequestRawAddAvoid(builder, t.Avoid) - ExecRequestRawAddProgData(builder, progDataOffset) + ExecRequestRawAddData(builder, dataOffset) execOptsOffset := t.ExecOpts.Pack(builder) ExecRequestRawAddExecOpts(builder, execOptsOffset) ExecRequestRawAddFlags(builder, t.Flags) @@ -1966,8 +1901,9 @@ func (t *ExecRequestRawT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffset func (rcv *ExecRequestRaw) UnPackTo(t *ExecRequestRawT) { t.Id = rcv.Id() + t.Type = rcv.Type() t.Avoid = rcv.Avoid() - t.ProgData = rcv.ProgDataBytes() + t.Data = rcv.DataBytes() t.ExecOpts = rcv.ExecOpts(nil).UnPack() t.Flags = rcv.Flags() allSignalLength := rcv.AllSignalLength() @@ -2025,20 +1961,32 @@ func (rcv *ExecRequestRaw) MutateId(n int64) bool { return rcv._tab.MutateInt64Slot(4, n) } -func (rcv *ExecRequestRaw) Avoid() uint64 { +func (rcv *ExecRequestRaw) Type() RequestType { o := flatbuffers.UOffsetT(rcv._tab.Offset(6)) if o != 0 { + return RequestType(rcv._tab.GetUint64(o + rcv._tab.Pos)) + } + return 0 +} + +func (rcv *ExecRequestRaw) MutateType(n RequestType) bool { + return rcv._tab.MutateUint64Slot(6, uint64(n)) +} + +func (rcv *ExecRequestRaw) Avoid() uint64 { + o := flatbuffers.UOffsetT(rcv._tab.Offset(8)) + if o != 0 { return rcv._tab.GetUint64(o + rcv._tab.Pos) } return 0 } func (rcv *ExecRequestRaw) MutateAvoid(n uint64) bool { - return rcv._tab.MutateUint64Slot(6, n) + return rcv._tab.MutateUint64Slot(8, n) } -func (rcv *ExecRequestRaw) ProgData(j int) byte { - o := flatbuffers.UOffsetT(rcv._tab.Offset(8)) +func (rcv *ExecRequestRaw) Data(j int) byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(10)) if o != 0 { a := rcv._tab.Vector(o) return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1)) @@ -2046,24 +1994,24 @@ func (rcv *ExecRequestRaw) ProgData(j int) byte { return 0 } -func (rcv *ExecRequestRaw) ProgDataLength() int { - o := flatbuffers.UOffsetT(rcv._tab.Offset(8)) +func (rcv *ExecRequestRaw) DataLength() int { + o := flatbuffers.UOffsetT(rcv._tab.Offset(10)) if o != 0 { return rcv._tab.VectorLen(o) } return 0 } -func (rcv *ExecRequestRaw) ProgDataBytes() []byte { - o := flatbuffers.UOffsetT(rcv._tab.Offset(8)) +func (rcv *ExecRequestRaw) DataBytes() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(10)) if o != 0 { return rcv._tab.ByteVector(o + rcv._tab.Pos) } return nil } -func (rcv *ExecRequestRaw) MutateProgData(j int, n byte) bool { - o := flatbuffers.UOffsetT(rcv._tab.Offset(8)) +func (rcv *ExecRequestRaw) MutateData(j int, n byte) bool { + o := flatbuffers.UOffsetT(rcv._tab.Offset(10)) if o != 0 { a := rcv._tab.Vector(o) return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n) @@ -2072,7 +2020,7 @@ func (rcv *ExecRequestRaw) MutateProgData(j int, n byte) bool { } func (rcv *ExecRequestRaw) ExecOpts(obj *ExecOptsRaw) *ExecOptsRaw { - o := flatbuffers.UOffsetT(rcv._tab.Offset(10)) + o := flatbuffers.UOffsetT(rcv._tab.Offset(12)) if o != 0 { x := o + rcv._tab.Pos if obj == nil { @@ -2085,7 +2033,7 @@ func (rcv *ExecRequestRaw) ExecOpts(obj *ExecOptsRaw) *ExecOptsRaw { } func (rcv *ExecRequestRaw) Flags() RequestFlag { - o := flatbuffers.UOffsetT(rcv._tab.Offset(12)) + o := flatbuffers.UOffsetT(rcv._tab.Offset(14)) if o != 0 { return RequestFlag(rcv._tab.GetUint64(o + rcv._tab.Pos)) } @@ -2093,11 +2041,11 @@ func (rcv *ExecRequestRaw) Flags() RequestFlag { } func (rcv *ExecRequestRaw) MutateFlags(n RequestFlag) bool { - return rcv._tab.MutateUint64Slot(12, uint64(n)) + return rcv._tab.MutateUint64Slot(14, uint64(n)) } func (rcv *ExecRequestRaw) AllSignal(j int) int32 { - o := flatbuffers.UOffsetT(rcv._tab.Offset(14)) + o := flatbuffers.UOffsetT(rcv._tab.Offset(16)) if o != 0 { a := rcv._tab.Vector(o) return rcv._tab.GetInt32(a + flatbuffers.UOffsetT(j*4)) @@ -2106,7 +2054,7 @@ func (rcv *ExecRequestRaw) AllSignal(j int) int32 { } func (rcv *ExecRequestRaw) AllSignalLength() int { - o := flatbuffers.UOffsetT(rcv._tab.Offset(14)) + o := flatbuffers.UOffsetT(rcv._tab.Offset(16)) if o != 0 { return rcv._tab.VectorLen(o) } @@ -2114,7 +2062,7 @@ func (rcv *ExecRequestRaw) AllSignalLength() int { } func (rcv *ExecRequestRaw) MutateAllSignal(j int, n int32) bool { - o := flatbuffers.UOffsetT(rcv._tab.Offset(14)) + o := flatbuffers.UOffsetT(rcv._tab.Offset(16)) if o != 0 { a := rcv._tab.Vector(o) return rcv._tab.MutateInt32(a+flatbuffers.UOffsetT(j*4), n) @@ -2123,28 +2071,31 @@ func (rcv *ExecRequestRaw) MutateAllSignal(j int, n int32) bool { } func ExecRequestRawStart(builder *flatbuffers.Builder) { - builder.StartObject(6) + builder.StartObject(7) } func ExecRequestRawAddId(builder *flatbuffers.Builder, id int64) { builder.PrependInt64Slot(0, id, 0) } +func ExecRequestRawAddType(builder *flatbuffers.Builder, type_ RequestType) { + builder.PrependUint64Slot(1, uint64(type_), 0) +} func ExecRequestRawAddAvoid(builder *flatbuffers.Builder, avoid uint64) { - builder.PrependUint64Slot(1, avoid, 0) + builder.PrependUint64Slot(2, avoid, 0) } -func ExecRequestRawAddProgData(builder *flatbuffers.Builder, progData flatbuffers.UOffsetT) { - builder.PrependUOffsetTSlot(2, flatbuffers.UOffsetT(progData), 0) +func ExecRequestRawAddData(builder *flatbuffers.Builder, data flatbuffers.UOffsetT) { + builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(data), 0) } -func ExecRequestRawStartProgDataVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { +func ExecRequestRawStartDataVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(1, numElems, 1) } func ExecRequestRawAddExecOpts(builder *flatbuffers.Builder, execOpts flatbuffers.UOffsetT) { - builder.PrependStructSlot(3, flatbuffers.UOffsetT(execOpts), 0) + builder.PrependStructSlot(4, flatbuffers.UOffsetT(execOpts), 0) } func ExecRequestRawAddFlags(builder *flatbuffers.Builder, flags RequestFlag) { - builder.PrependUint64Slot(4, uint64(flags), 0) + builder.PrependUint64Slot(5, uint64(flags), 0) } func ExecRequestRawAddAllSignal(builder *flatbuffers.Builder, allSignal flatbuffers.UOffsetT) { - builder.PrependUOffsetTSlot(5, flatbuffers.UOffsetT(allSignal), 0) + builder.PrependUOffsetTSlot(6, flatbuffers.UOffsetT(allSignal), 0) } func ExecRequestRawStartAllSignalVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems, 4) diff --git a/pkg/flatrpc/flatrpc.h b/pkg/flatrpc/flatrpc.h index 94e1c15f6..12d905c12 100644 --- a/pkg/flatrpc/flatrpc.h +++ b/pkg/flatrpc/flatrpc.h @@ -486,18 +486,49 @@ struct ExecutorMessagesRawUnion { bool VerifyExecutorMessagesRaw(flatbuffers::Verifier &verifier, const void *obj, ExecutorMessagesRaw type); bool VerifyExecutorMessagesRawVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<ExecutorMessagesRaw> *types); +enum class RequestType : uint64_t { + Program = 0, + Binary = 1ULL, + Glob = 2ULL, + MIN = Program, + MAX = Glob +}; + +inline const RequestType (&EnumValuesRequestType())[3] { + static const RequestType values[] = { + RequestType::Program, + RequestType::Binary, + RequestType::Glob + }; + return values; +} + +inline const char * const *EnumNamesRequestType() { + static const char * const names[4] = { + "Program", + "Binary", + "Glob", + nullptr + }; + return names; +} + +inline const char *EnumNameRequestType(RequestType e) { + if (flatbuffers::IsOutRange(e, RequestType::Program, RequestType::Glob)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesRequestType()[index]; +} + enum class RequestFlag : uint64_t { - IsBinary = 1ULL, - ReturnOutput = 2ULL, - ReturnError = 4ULL, + ReturnOutput = 1ULL, + ReturnError = 2ULL, NONE = 0, - ANY = 7ULL + ANY = 3ULL }; FLATBUFFERS_DEFINE_BITMASK_OPERATORS(RequestFlag, uint64_t) -inline const RequestFlag (&EnumValuesRequestFlag())[3] { +inline const RequestFlag (&EnumValuesRequestFlag())[2] { static const RequestFlag values[] = { - RequestFlag::IsBinary, RequestFlag::ReturnOutput, RequestFlag::ReturnError }; @@ -505,10 +536,8 @@ inline const RequestFlag (&EnumValuesRequestFlag())[3] { } inline const char * const *EnumNamesRequestFlag() { - static const char * const names[5] = { - "IsBinary", + static const char * const names[3] = { "ReturnOutput", - "", "ReturnError", nullptr }; @@ -516,8 +545,8 @@ inline const char * const *EnumNamesRequestFlag() { } inline const char *EnumNameRequestFlag(RequestFlag e) { - if (flatbuffers::IsOutRange(e, RequestFlag::IsBinary, RequestFlag::ReturnError)) return ""; - const size_t index = static_cast<size_t>(e) - static_cast<size_t>(RequestFlag::IsBinary); + if (flatbuffers::IsOutRange(e, RequestFlag::ReturnOutput, RequestFlag::ReturnError)) return ""; + const size_t index = static_cast<size_t>(e) - static_cast<size_t>(RequestFlag::ReturnOutput); return EnumNamesRequestFlag()[index]; } @@ -936,7 +965,6 @@ struct ConnectReplyRawT : public flatbuffers::NativeTable { std::vector<std::string> race_frames{}; rpc::Feature features = static_cast<rpc::Feature>(0); std::vector<std::string> files{}; - std::vector<std::string> globs{}; }; struct ConnectReplyRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { @@ -954,8 +982,7 @@ struct ConnectReplyRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_LEAK_FRAMES = 20, VT_RACE_FRAMES = 22, VT_FEATURES = 24, - VT_FILES = 26, - VT_GLOBS = 28 + VT_FILES = 26 }; bool debug() const { return GetField<uint8_t>(VT_DEBUG, 0) != 0; @@ -993,9 +1020,6 @@ struct ConnectReplyRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *files() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_FILES); } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *globs() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_GLOBS); - } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_DEBUG, 1) && @@ -1016,9 +1040,6 @@ struct ConnectReplyRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyOffset(verifier, VT_FILES) && verifier.VerifyVector(files()) && verifier.VerifyVectorOfStrings(files()) && - VerifyOffset(verifier, VT_GLOBS) && - verifier.VerifyVector(globs()) && - verifier.VerifyVectorOfStrings(globs()) && verifier.EndTable(); } ConnectReplyRawT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; @@ -1066,9 +1087,6 @@ struct ConnectReplyRawBuilder { void add_files(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> files) { fbb_.AddOffset(ConnectReplyRaw::VT_FILES, files); } - void add_globs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> globs) { - fbb_.AddOffset(ConnectReplyRaw::VT_GLOBS, globs); - } explicit ConnectReplyRawBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); @@ -1093,11 +1111,9 @@ inline flatbuffers::Offset<ConnectReplyRaw> CreateConnectReplyRaw( flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> leak_frames = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> race_frames = 0, rpc::Feature features = static_cast<rpc::Feature>(0), - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> files = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> globs = 0) { + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> files = 0) { ConnectReplyRawBuilder builder_(_fbb); builder_.add_features(features); - builder_.add_globs(globs); builder_.add_files(files); builder_.add_race_frames(race_frames); builder_.add_leak_frames(leak_frames); @@ -1125,12 +1141,10 @@ inline flatbuffers::Offset<ConnectReplyRaw> CreateConnectReplyRawDirect( const std::vector<flatbuffers::Offset<flatbuffers::String>> *leak_frames = nullptr, const std::vector<flatbuffers::Offset<flatbuffers::String>> *race_frames = nullptr, rpc::Feature features = static_cast<rpc::Feature>(0), - const std::vector<flatbuffers::Offset<flatbuffers::String>> *files = nullptr, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *globs = nullptr) { + const std::vector<flatbuffers::Offset<flatbuffers::String>> *files = nullptr) { auto leak_frames__ = leak_frames ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*leak_frames) : 0; auto race_frames__ = race_frames ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*race_frames) : 0; auto files__ = files ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*files) : 0; - auto globs__ = globs ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*globs) : 0; return rpc::CreateConnectReplyRaw( _fbb, debug, @@ -1144,8 +1158,7 @@ inline flatbuffers::Offset<ConnectReplyRaw> CreateConnectReplyRawDirect( leak_frames__, race_frames__, features, - files__, - globs__); + files__); } flatbuffers::Offset<ConnectReplyRaw> CreateConnectReplyRaw(flatbuffers::FlatBufferBuilder &_fbb, const ConnectReplyRawT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); @@ -1155,7 +1168,6 @@ struct InfoRequestRawT : public flatbuffers::NativeTable { std::string error{}; std::vector<std::unique_ptr<rpc::FeatureInfoRawT>> features{}; std::vector<std::unique_ptr<rpc::FileInfoRawT>> files{}; - std::vector<std::unique_ptr<rpc::GlobInfoRawT>> globs{}; InfoRequestRawT() = default; InfoRequestRawT(const InfoRequestRawT &o); InfoRequestRawT(InfoRequestRawT&&) FLATBUFFERS_NOEXCEPT = default; @@ -1168,8 +1180,7 @@ struct InfoRequestRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ERROR = 4, VT_FEATURES = 6, - VT_FILES = 8, - VT_GLOBS = 10 + VT_FILES = 8 }; const flatbuffers::String *error() const { return GetPointer<const flatbuffers::String *>(VT_ERROR); @@ -1180,9 +1191,6 @@ struct InfoRequestRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector<flatbuffers::Offset<rpc::FileInfoRaw>> *files() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<rpc::FileInfoRaw>> *>(VT_FILES); } - const flatbuffers::Vector<flatbuffers::Offset<rpc::GlobInfoRaw>> *globs() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<rpc::GlobInfoRaw>> *>(VT_GLOBS); - } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_ERROR) && @@ -1193,9 +1201,6 @@ struct InfoRequestRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyOffset(verifier, VT_FILES) && verifier.VerifyVector(files()) && verifier.VerifyVectorOfTables(files()) && - VerifyOffset(verifier, VT_GLOBS) && - verifier.VerifyVector(globs()) && - verifier.VerifyVectorOfTables(globs()) && verifier.EndTable(); } InfoRequestRawT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; @@ -1216,9 +1221,6 @@ struct InfoRequestRawBuilder { void add_files(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<rpc::FileInfoRaw>>> files) { fbb_.AddOffset(InfoRequestRaw::VT_FILES, files); } - void add_globs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<rpc::GlobInfoRaw>>> globs) { - fbb_.AddOffset(InfoRequestRaw::VT_GLOBS, globs); - } explicit InfoRequestRawBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); @@ -1234,10 +1236,8 @@ inline flatbuffers::Offset<InfoRequestRaw> CreateInfoRequestRaw( flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset<flatbuffers::String> error = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<rpc::FeatureInfoRaw>>> features = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<rpc::FileInfoRaw>>> files = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<rpc::GlobInfoRaw>>> globs = 0) { + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<rpc::FileInfoRaw>>> files = 0) { InfoRequestRawBuilder builder_(_fbb); - builder_.add_globs(globs); builder_.add_files(files); builder_.add_features(features); builder_.add_error(error); @@ -1248,18 +1248,15 @@ inline flatbuffers::Offset<InfoRequestRaw> CreateInfoRequestRawDirect( flatbuffers::FlatBufferBuilder &_fbb, const char *error = nullptr, const std::vector<flatbuffers::Offset<rpc::FeatureInfoRaw>> *features = nullptr, - const std::vector<flatbuffers::Offset<rpc::FileInfoRaw>> *files = nullptr, - const std::vector<flatbuffers::Offset<rpc::GlobInfoRaw>> *globs = nullptr) { + const std::vector<flatbuffers::Offset<rpc::FileInfoRaw>> *files = nullptr) { auto error__ = error ? _fbb.CreateString(error) : 0; auto features__ = features ? _fbb.CreateVector<flatbuffers::Offset<rpc::FeatureInfoRaw>>(*features) : 0; auto files__ = files ? _fbb.CreateVector<flatbuffers::Offset<rpc::FileInfoRaw>>(*files) : 0; - auto globs__ = globs ? _fbb.CreateVector<flatbuffers::Offset<rpc::GlobInfoRaw>>(*globs) : 0; return rpc::CreateInfoRequestRaw( _fbb, error__, features__, - files__, - globs__); + files__); } flatbuffers::Offset<InfoRequestRaw> CreateInfoRequestRaw(flatbuffers::FlatBufferBuilder &_fbb, const InfoRequestRawT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); @@ -1777,8 +1774,9 @@ flatbuffers::Offset<ExecutorMessageRaw> CreateExecutorMessageRaw(flatbuffers::Fl struct ExecRequestRawT : public flatbuffers::NativeTable { typedef ExecRequestRaw TableType; int64_t id = 0; + rpc::RequestType type = rpc::RequestType::Program; uint64_t avoid = 0; - std::vector<uint8_t> prog_data{}; + std::vector<uint8_t> data{}; std::unique_ptr<rpc::ExecOptsRaw> exec_opts{}; rpc::RequestFlag flags = static_cast<rpc::RequestFlag>(0); std::vector<int32_t> all_signal{}; @@ -1793,20 +1791,24 @@ struct ExecRequestRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef ExecRequestRawBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ID = 4, - VT_AVOID = 6, - VT_PROG_DATA = 8, - VT_EXEC_OPTS = 10, - VT_FLAGS = 12, - VT_ALL_SIGNAL = 14 + VT_TYPE = 6, + VT_AVOID = 8, + VT_DATA = 10, + VT_EXEC_OPTS = 12, + VT_FLAGS = 14, + VT_ALL_SIGNAL = 16 }; int64_t id() const { return GetField<int64_t>(VT_ID, 0); } + rpc::RequestType type() const { + return static_cast<rpc::RequestType>(GetField<uint64_t>(VT_TYPE, 0)); + } uint64_t avoid() const { return GetField<uint64_t>(VT_AVOID, 0); } - const flatbuffers::Vector<uint8_t> *prog_data() const { - return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_PROG_DATA); + const flatbuffers::Vector<uint8_t> *data() const { + return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_DATA); } const rpc::ExecOptsRaw *exec_opts() const { return GetStruct<const rpc::ExecOptsRaw *>(VT_EXEC_OPTS); @@ -1820,9 +1822,10 @@ struct ExecRequestRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField<int64_t>(verifier, VT_ID, 8) && + VerifyField<uint64_t>(verifier, VT_TYPE, 8) && VerifyField<uint64_t>(verifier, VT_AVOID, 8) && - VerifyOffset(verifier, VT_PROG_DATA) && - verifier.VerifyVector(prog_data()) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && VerifyField<rpc::ExecOptsRaw>(verifier, VT_EXEC_OPTS, 8) && VerifyField<uint64_t>(verifier, VT_FLAGS, 8) && VerifyOffset(verifier, VT_ALL_SIGNAL) && @@ -1841,11 +1844,14 @@ struct ExecRequestRawBuilder { void add_id(int64_t id) { fbb_.AddElement<int64_t>(ExecRequestRaw::VT_ID, id, 0); } + void add_type(rpc::RequestType type) { + fbb_.AddElement<uint64_t>(ExecRequestRaw::VT_TYPE, static_cast<uint64_t>(type), 0); + } void add_avoid(uint64_t avoid) { fbb_.AddElement<uint64_t>(ExecRequestRaw::VT_AVOID, avoid, 0); } - void add_prog_data(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> prog_data) { - fbb_.AddOffset(ExecRequestRaw::VT_PROG_DATA, prog_data); + void add_data(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data) { + fbb_.AddOffset(ExecRequestRaw::VT_DATA, data); } void add_exec_opts(const rpc::ExecOptsRaw *exec_opts) { fbb_.AddStruct(ExecRequestRaw::VT_EXEC_OPTS, exec_opts); @@ -1870,36 +1876,40 @@ struct ExecRequestRawBuilder { inline flatbuffers::Offset<ExecRequestRaw> CreateExecRequestRaw( flatbuffers::FlatBufferBuilder &_fbb, int64_t id = 0, + rpc::RequestType type = rpc::RequestType::Program, uint64_t avoid = 0, - flatbuffers::Offset<flatbuffers::Vector<uint8_t>> prog_data = 0, + flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data = 0, const rpc::ExecOptsRaw *exec_opts = nullptr, rpc::RequestFlag flags = static_cast<rpc::RequestFlag>(0), flatbuffers::Offset<flatbuffers::Vector<int32_t>> all_signal = 0) { ExecRequestRawBuilder builder_(_fbb); builder_.add_flags(flags); builder_.add_avoid(avoid); + builder_.add_type(type); builder_.add_id(id); builder_.add_all_signal(all_signal); builder_.add_exec_opts(exec_opts); - builder_.add_prog_data(prog_data); + builder_.add_data(data); return builder_.Finish(); } inline flatbuffers::Offset<ExecRequestRaw> CreateExecRequestRawDirect( flatbuffers::FlatBufferBuilder &_fbb, int64_t id = 0, + rpc::RequestType type = rpc::RequestType::Program, uint64_t avoid = 0, - const std::vector<uint8_t> *prog_data = nullptr, + const std::vector<uint8_t> *data = nullptr, const rpc::ExecOptsRaw *exec_opts = nullptr, rpc::RequestFlag flags = static_cast<rpc::RequestFlag>(0), const std::vector<int32_t> *all_signal = nullptr) { - auto prog_data__ = prog_data ? _fbb.CreateVector<uint8_t>(*prog_data) : 0; + auto data__ = data ? _fbb.CreateVector<uint8_t>(*data) : 0; auto all_signal__ = all_signal ? _fbb.CreateVector<int32_t>(*all_signal) : 0; return rpc::CreateExecRequestRaw( _fbb, id, + type, avoid, - prog_data__, + data__, exec_opts, flags, all_signal__); @@ -2942,7 +2952,6 @@ inline void ConnectReplyRaw::UnPackTo(ConnectReplyRawT *_o, const flatbuffers::r { auto _e = race_frames(); if (_e) { _o->race_frames.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->race_frames[_i] = _e->Get(_i)->str(); } } } { auto _e = features(); _o->features = _e; } { auto _e = files(); if (_e) { _o->files.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->files[_i] = _e->Get(_i)->str(); } } } - { auto _e = globs(); if (_e) { _o->globs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->globs[_i] = _e->Get(_i)->str(); } } } } inline flatbuffers::Offset<ConnectReplyRaw> ConnectReplyRaw::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ConnectReplyRawT* _o, const flatbuffers::rehasher_function_t *_rehasher) { @@ -2965,7 +2974,6 @@ inline flatbuffers::Offset<ConnectReplyRaw> CreateConnectReplyRaw(flatbuffers::F auto _race_frames = _o->race_frames.size() ? _fbb.CreateVectorOfStrings(_o->race_frames) : 0; auto _features = _o->features; auto _files = _o->files.size() ? _fbb.CreateVectorOfStrings(_o->files) : 0; - auto _globs = _o->globs.size() ? _fbb.CreateVectorOfStrings(_o->globs) : 0; return rpc::CreateConnectReplyRaw( _fbb, _debug, @@ -2979,8 +2987,7 @@ inline flatbuffers::Offset<ConnectReplyRaw> CreateConnectReplyRaw(flatbuffers::F _leak_frames, _race_frames, _features, - _files, - _globs); + _files); } inline InfoRequestRawT::InfoRequestRawT(const InfoRequestRawT &o) @@ -2989,15 +2996,12 @@ inline InfoRequestRawT::InfoRequestRawT(const InfoRequestRawT &o) for (const auto &features_ : o.features) { features.emplace_back((features_) ? new rpc::FeatureInfoRawT(*features_) : nullptr); } files.reserve(o.files.size()); for (const auto &files_ : o.files) { files.emplace_back((files_) ? new rpc::FileInfoRawT(*files_) : nullptr); } - globs.reserve(o.globs.size()); - for (const auto &globs_ : o.globs) { globs.emplace_back((globs_) ? new rpc::GlobInfoRawT(*globs_) : nullptr); } } inline InfoRequestRawT &InfoRequestRawT::operator=(InfoRequestRawT o) FLATBUFFERS_NOEXCEPT { std::swap(error, o.error); std::swap(features, o.features); std::swap(files, o.files); - std::swap(globs, o.globs); return *this; } @@ -3013,7 +3017,6 @@ inline void InfoRequestRaw::UnPackTo(InfoRequestRawT *_o, const flatbuffers::res { auto _e = error(); if (_e) _o->error = _e->str(); } { auto _e = features(); if (_e) { _o->features.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->features[_i] = std::unique_ptr<rpc::FeatureInfoRawT>(_e->Get(_i)->UnPack(_resolver)); } } } { auto _e = files(); if (_e) { _o->files.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->files[_i] = std::unique_ptr<rpc::FileInfoRawT>(_e->Get(_i)->UnPack(_resolver)); } } } - { auto _e = globs(); if (_e) { _o->globs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->globs[_i] = std::unique_ptr<rpc::GlobInfoRawT>(_e->Get(_i)->UnPack(_resolver)); } } } } inline flatbuffers::Offset<InfoRequestRaw> InfoRequestRaw::Pack(flatbuffers::FlatBufferBuilder &_fbb, const InfoRequestRawT* _o, const flatbuffers::rehasher_function_t *_rehasher) { @@ -3027,13 +3030,11 @@ inline flatbuffers::Offset<InfoRequestRaw> CreateInfoRequestRaw(flatbuffers::Fla auto _error = _o->error.empty() ? 0 : _fbb.CreateString(_o->error); auto _features = _o->features.size() ? _fbb.CreateVector<flatbuffers::Offset<rpc::FeatureInfoRaw>> (_o->features.size(), [](size_t i, _VectorArgs *__va) { return CreateFeatureInfoRaw(*__va->__fbb, __va->__o->features[i].get(), __va->__rehasher); }, &_va ) : 0; auto _files = _o->files.size() ? _fbb.CreateVector<flatbuffers::Offset<rpc::FileInfoRaw>> (_o->files.size(), [](size_t i, _VectorArgs *__va) { return CreateFileInfoRaw(*__va->__fbb, __va->__o->files[i].get(), __va->__rehasher); }, &_va ) : 0; - auto _globs = _o->globs.size() ? _fbb.CreateVector<flatbuffers::Offset<rpc::GlobInfoRaw>> (_o->globs.size(), [](size_t i, _VectorArgs *__va) { return CreateGlobInfoRaw(*__va->__fbb, __va->__o->globs[i].get(), __va->__rehasher); }, &_va ) : 0; return rpc::CreateInfoRequestRaw( _fbb, _error, _features, - _files, - _globs); + _files); } inline InfoReplyRawT *InfoReplyRaw::UnPack(const flatbuffers::resolver_function_t *_resolver) const { @@ -3218,8 +3219,9 @@ inline flatbuffers::Offset<ExecutorMessageRaw> CreateExecutorMessageRaw(flatbuff inline ExecRequestRawT::ExecRequestRawT(const ExecRequestRawT &o) : id(o.id), + type(o.type), avoid(o.avoid), - prog_data(o.prog_data), + data(o.data), exec_opts((o.exec_opts) ? new rpc::ExecOptsRaw(*o.exec_opts) : nullptr), flags(o.flags), all_signal(o.all_signal) { @@ -3227,8 +3229,9 @@ inline ExecRequestRawT::ExecRequestRawT(const ExecRequestRawT &o) inline ExecRequestRawT &ExecRequestRawT::operator=(ExecRequestRawT o) FLATBUFFERS_NOEXCEPT { std::swap(id, o.id); + std::swap(type, o.type); std::swap(avoid, o.avoid); - std::swap(prog_data, o.prog_data); + std::swap(data, o.data); std::swap(exec_opts, o.exec_opts); std::swap(flags, o.flags); std::swap(all_signal, o.all_signal); @@ -3245,8 +3248,9 @@ inline void ExecRequestRaw::UnPackTo(ExecRequestRawT *_o, const flatbuffers::res (void)_o; (void)_resolver; { auto _e = id(); _o->id = _e; } + { auto _e = type(); _o->type = _e; } { auto _e = avoid(); _o->avoid = _e; } - { auto _e = prog_data(); if (_e) { _o->prog_data.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->prog_data.begin()); } } + { auto _e = data(); if (_e) { _o->data.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->data.begin()); } } { auto _e = exec_opts(); if (_e) _o->exec_opts = std::unique_ptr<rpc::ExecOptsRaw>(new rpc::ExecOptsRaw(*_e)); } { auto _e = flags(); _o->flags = _e; } { auto _e = all_signal(); if (_e) { _o->all_signal.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->all_signal[_i] = _e->Get(_i); } } } @@ -3261,16 +3265,18 @@ inline flatbuffers::Offset<ExecRequestRaw> CreateExecRequestRaw(flatbuffers::Fla (void)_o; struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ExecRequestRawT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; auto _id = _o->id; + auto _type = _o->type; auto _avoid = _o->avoid; - auto _prog_data = _o->prog_data.size() ? _fbb.CreateVector(_o->prog_data) : 0; + auto _data = _o->data.size() ? _fbb.CreateVector(_o->data) : 0; auto _exec_opts = _o->exec_opts ? _o->exec_opts.get() : nullptr; auto _flags = _o->flags; auto _all_signal = _o->all_signal.size() ? _fbb.CreateVector(_o->all_signal) : 0; return rpc::CreateExecRequestRaw( _fbb, _id, + _type, _avoid, - _prog_data, + _data, _exec_opts, _flags, _all_signal); diff --git a/pkg/fuzzer/queue/queue.go b/pkg/fuzzer/queue/queue.go index 1d25cbc8a..05d9cfbed 100644 --- a/pkg/fuzzer/queue/queue.go +++ b/pkg/fuzzer/queue/queue.go @@ -9,6 +9,7 @@ import ( "encoding/gob" "fmt" "math/rand" + "strings" "sync" "sync/atomic" @@ -20,8 +21,15 @@ import ( ) type Request struct { - Prog *prog.Prog - ExecOpts flatrpc.ExecOpts + // Type of the request. + // RequestTypeProgram executes Prog, and is used by most requests (also the default zero value). + // RequestTypeBinary executes binary with file name stored in Data. + // RequestTypeGlob expands glob pattern stored in Data. + Type flatrpc.RequestType + ExecOpts flatrpc.ExecOpts + Prog *prog.Prog // for RequestTypeProgram + BinaryFile string // for RequestTypeBinary + GlobPattern string // for RequestTypeGlob // If specified, the resulting signal for call SignalFilterCall // will include subset of it even if it's not new. @@ -36,9 +44,6 @@ type Request struct { // This stat will be incremented on request completion. Stat *stat.Val - // Options needed by runtest. - BinaryFile string // If set, it's executed instead of Prog. - // Important requests will be retried even from crashed VMs. Important bool @@ -123,20 +128,51 @@ func (r *Request) Validate() error { if (collectComps) && (collectSignal || collectCover) { return fmt.Errorf("hint collection is mutually exclusive with signal/coverage") } - sandboxes := flatrpc.ExecEnvSandboxNone | flatrpc.ExecEnvSandboxSetuid | - flatrpc.ExecEnvSandboxNamespace | flatrpc.ExecEnvSandboxAndroid - if r.BinaryFile == "" && r.ExecOpts.EnvFlags&sandboxes == 0 { - return fmt.Errorf("no sandboxes set") + switch r.Type { + case flatrpc.RequestTypeProgram: + if r.Prog == nil { + return fmt.Errorf("program is not set") + } + sandboxes := flatrpc.ExecEnvSandboxNone | flatrpc.ExecEnvSandboxSetuid | + flatrpc.ExecEnvSandboxNamespace | flatrpc.ExecEnvSandboxAndroid + if r.ExecOpts.EnvFlags&sandboxes == 0 { + return fmt.Errorf("no sandboxes set") + } + case flatrpc.RequestTypeBinary: + if r.BinaryFile == "" { + return fmt.Errorf("binary file name is not set") + } + case flatrpc.RequestTypeGlob: + if r.GlobPattern == "" { + return fmt.Errorf("glob pattern is not set") + } + default: + return fmt.Errorf("unknown request type") } return nil } func (r *Request) hash() hash.Sig { buf := new(bytes.Buffer) - if err := gob.NewEncoder(buf).Encode(r.ExecOpts); err != nil { + enc := gob.NewEncoder(buf) + if err := enc.Encode(r.Type); err != nil { + panic(err) + } + if err := enc.Encode(r.ExecOpts); err != nil { panic(err) } - return hash.Hash(r.Prog.Serialize(), buf.Bytes()) + var data []byte + switch r.Type { + case flatrpc.RequestTypeProgram: + data = r.Prog.Serialize() + case flatrpc.RequestTypeBinary: + data = []byte(r.BinaryFile) + case flatrpc.RequestTypeGlob: + data = []byte(r.GlobPattern) + default: + panic("unknown request type") + } + return hash.Hash(data, buf.Bytes()) } func (r *Request) initChannel() { @@ -172,6 +208,15 @@ func (r *Result) Stop() bool { } } +// Globs returns result of RequestTypeGlob. +func (r *Result) GlobFiles() []string { + out := strings.Trim(string(r.Output), "\000") + if out == "" { + return nil + } + return strings.Split(out, "\000") +} + type Status int const ( diff --git a/pkg/fuzzer/queue/queue_test.go b/pkg/fuzzer/queue/queue_test.go index 5b6a03ed0..d1909e50c 100644 --- a/pkg/fuzzer/queue/queue_test.go +++ b/pkg/fuzzer/queue/queue_test.go @@ -43,3 +43,10 @@ func TestPrioQueue(t *testing.T) { assert.Equal(t, req4, pq.Next()) assert.Equal(t, req3, pq.Next()) } + +func TestGlobFiles(t *testing.T) { + r := &Result{} + assert.Equal(t, r.GlobFiles(), []string(nil)) + r.Output = []byte{'a', 'b', 0, 'c', 0} + assert.Equal(t, r.GlobFiles(), []string{"ab", "c"}) +} diff --git a/pkg/ifaceprobe/ifaceprobe.go b/pkg/ifaceprobe/ifaceprobe.go index f3ab8ba4a..b2b3569df 100644 --- a/pkg/ifaceprobe/ifaceprobe.go +++ b/pkg/ifaceprobe/ifaceprobe.go @@ -12,7 +12,9 @@ import ( "path/filepath" "slices" "strings" + "sync" + "github.com/google/syzkaller/pkg/csource" "github.com/google/syzkaller/pkg/flatrpc" "github.com/google/syzkaller/pkg/fuzzer/queue" "github.com/google/syzkaller/pkg/log" @@ -38,71 +40,62 @@ type PCInfo struct { File string } -// Globs returns a list of glob's that should be requested from the target machine. -// Result of querying these globs should be later passed to Run in info. -func Globs() []string { - var globs []string - for _, path := range []string{"/dev", "/sys", "/proc"} { - // Our globs currently do not support recursion (#4906), - // so we append N "/*" parts manully. Some of the paths can be very deep, e.g. try: - // sudo find /sys -ls 2>/dev/null | sed "s#[^/]##g" | sort | uniq -c - for i := 1; i < 15; i++ { - globs = append(globs, path+strings.Repeat("/*", i)) - } - } - return globs -} - -// Run finishes dynamic analysis and returns dynamic info. +// Run does dynamic analysis and returns dynamic info. // As it runs it will submit some test program requests to the exec queue. -// Info is used to extract results of glob querying, see Globs function. -func Run(ctx context.Context, cfg *mgrconfig.Config, exec queue.Executor, info *flatrpc.InfoRequest) (*Info, error) { +func Run(ctx context.Context, cfg *mgrconfig.Config, features flatrpc.Feature, exec queue.Executor) (*Info, error) { return (&prober{ - ctx: ctx, - cfg: cfg, - exec: exec, - info: info, + ctx: ctx, + cfg: cfg, + features: features, + exec: exec, + done: make(chan *fileDesc, 100), + errc: make(chan error, 1), }).run() } type prober struct { - ctx context.Context - cfg *mgrconfig.Config - exec queue.Executor - info *flatrpc.InfoRequest + ctx context.Context + cfg *mgrconfig.Config + features flatrpc.Feature + exec queue.Executor + wg sync.WaitGroup + done chan *fileDesc + errc chan error +} + +type fileDesc struct { + file string + results []*queue.Result } func (pr *prober) run() (*Info, error) { symb := symbolizer.NewSymbolizer(pr.cfg.SysTarget) defer symb.Close() - files := extractFiles(pr.info) - var reqs [][]*queue.Request - for _, file := range extractFiles(pr.info) { - reqs1, err := pr.submitFile(file) - if err != nil { - return nil, err - } - reqs = append(reqs, reqs1) + for _, glob := range globList() { + pr.submitGlob(glob) } + go func() { + pr.wg.Wait() + close(pr.done) + }() + info := &Info{} dedup := make(map[uint64]bool) kernelObj := filepath.Join(pr.cfg.KernelObj, pr.cfg.SysTarget.KernelObject) sourceBase := filepath.Clean(pr.cfg.KernelSrc) + string(filepath.Separator) - for i, file := range files { + i := 0 + for desc := range pr.done { + i++ if i%500 == 0 { - log.Logf(0, "processing file %v/%v", i, len(files)) + log.Logf(0, "done file %v", i) } fi := FileInfo{ - Name: file, + Name: desc.file, } fileDedup := make(map[uint64]bool) - for _, req := range reqs[i] { - res := req.Wait(pr.ctx) - if res.Status != queue.Success { - return nil, fmt.Errorf("failed to execute prog: %w (%v)", res.Err, res.Status) - } + for _, res := range desc.results { cover := append(res.Info.Calls[0].Cover, res.Info.Calls[1].Cover...) for _, pc := range cover { if fileDedup[pc] { @@ -133,13 +126,59 @@ func (pr *prober) run() (*Info, error) { slices.Sort(fi.Cover) info.Files = append(info.Files, fi) } + slices.SortFunc(info.Files, func(a, b FileInfo) int { + return strings.Compare(a.Name, b.Name) + }) slices.SortFunc(info.PCs, func(a, b PCInfo) int { return int(a.PC - b.PC) }) - return info, nil + select { + case err := <-pr.errc: + return nil, err + default: + return info, nil + } +} + +func (pr *prober) noteError(err error) { + select { + case pr.errc <- err: + default: + } } -func (pr *prober) submitFile(file string) ([]*queue.Request, error) { +func (pr *prober) submitGlob(glob string) { + pr.wg.Add(1) + req := &queue.Request{ + Type: flatrpc.RequestTypeGlob, + GlobPattern: glob, + ExecOpts: flatrpc.ExecOpts{ + EnvFlags: flatrpc.ExecEnvSandboxNone | csource.FeaturesToFlags(pr.features, nil), + }, + Important: true, + } + req.OnDone(pr.onGlobDone) + pr.exec.Submit(req) +} + +func (pr *prober) onGlobDone(req *queue.Request, res *queue.Result) bool { + defer pr.wg.Done() + if res.Status != queue.Success { + pr.noteError(fmt.Errorf("failed to execute glob: %w (%v)\n%s\n%s", + res.Err, res.Status, req.GlobPattern, res.Output)) + } + files := res.GlobFiles() + log.Logf(0, "glob %v expanded to %v files", req.GlobPattern, len(files)) + for _, file := range files { + if extractFileFilter(file) { + pr.submitFile(file) + } + } + return true +} + +func (pr *prober) submitFile(file string) { + pr.wg.Add(1) var fops = []struct { mode string call string @@ -151,18 +190,22 @@ func (pr *prober) submitFile(file string) ([]*queue.Request, error) { {mode: "O_RDONLY", call: "mmap(0x0, 0x1000, 0x1, 0x2, r0, 0)"}, {mode: "O_WRONLY", call: "mmap(0x0, 0x1000, 0x2, 0x2, r0, 0)"}, } + desc := &fileDesc{ + file: file, + } var reqs []*queue.Request for _, desc := range fops { text := fmt.Sprintf("r0 = openat(0x%x, &AUTO='%s', 0x%x, 0x0)\n%v", pr.constVal("AT_FDCWD"), file, pr.constVal(desc.mode), desc.call) p, err := pr.cfg.Target.Deserialize([]byte(text), prog.StrictUnsafe) if err != nil { - return nil, fmt.Errorf("failed to deserialize: %w\n%v", err, text) + panic(fmt.Sprintf("failed to deserialize: %v\n%v", err, text)) } req := &queue.Request{ Prog: p, ExecOpts: flatrpc.ExecOpts{ - EnvFlags: flatrpc.ExecEnvSandboxNone | flatrpc.ExecEnvSignal, + EnvFlags: flatrpc.ExecEnvSandboxNone | flatrpc.ExecEnvSignal | + csource.FeaturesToFlags(pr.features, nil), ExecFlags: flatrpc.ExecFlagCollectCover, }, Important: true, @@ -170,7 +213,19 @@ func (pr *prober) submitFile(file string) ([]*queue.Request, error) { reqs = append(reqs, req) pr.exec.Submit(req) } - return reqs, nil + go func() { + defer pr.wg.Done() + for _, req := range reqs { + res := req.Wait(pr.ctx) + if res.Status != queue.Success { + pr.noteError(fmt.Errorf("failed to execute prog: %w (%v)\n%s\n%s", + res.Err, res.Status, req.Prog.Serialize(), res.Output)) + continue + } + desc.results = append(desc.results, res) + } + pr.done <- desc + }() } func (pr *prober) constVal(name string) uint64 { @@ -181,23 +236,27 @@ func (pr *prober) constVal(name string) uint64 { return val } -func extractFiles(info *flatrpc.InfoRequestRawT) []string { - var files []string - dedup := make(map[string]bool) - for _, glob := range info.Globs { - for _, file := range glob.Files { - if dedup[file] || !extractFileFilter(file) { - continue - } - dedup[file] = true - files = append(files, file) +// globList returns a list of glob's we are interested in. +func globList() []string { + var globs []string + // /selinux is mounted by executor, we probably should mount it at the standard /sys/fs/selinux, + // but this is where it is now. + // Also query the test cwd, executor creates some links in there. + for _, path := range []string{"/dev", "/sys", "/proc", "/selinux", "."} { + // Our globs currently do not support recursion (#4906), + // so we append N "/*" parts manully. Some of the paths can be very deep, e.g. try: + // sudo find /sys -ls 2>/dev/null | sed "s#[^/]##g" | sort | uniq -c + for i := 1; i < 15; i++ { + globs = append(globs, path+strings.Repeat("/*", i)) } } - return files + return globs } func extractFileFilter(file string) bool { - if strings.HasPrefix(file, "/dev/") { + if strings.HasPrefix(file, "/dev/") || + strings.HasPrefix(file, "/selinux/") || + strings.HasPrefix(file, "./") { return true } if proc := "/proc/"; strings.HasPrefix(file, proc) { @@ -234,5 +293,5 @@ func extractFileFilter(file string) bool { } return true } - return false + panic(fmt.Sprintf("unhandled file %q", file)) } diff --git a/pkg/rpcserver/local.go b/pkg/rpcserver/local.go index c8052138a..5faa8334b 100644 --- a/pkg/rpcserver/local.go +++ b/pkg/rpcserver/local.go @@ -112,8 +112,7 @@ type local struct { setupDone chan bool } -func (ctx *local) MachineChecked(info *flatrpc.InfoRequest, features flatrpc.Feature, - syscalls map[*prog.Syscall]bool) queue.Source { +func (ctx *local) MachineChecked(features flatrpc.Feature, syscalls map[*prog.Syscall]bool) queue.Source { <-ctx.setupDone ctx.serv.TriagedCorpus() return ctx.cfg.MachineChecked(features, syscalls) diff --git a/pkg/rpcserver/mocks/Manager.go b/pkg/rpcserver/mocks/Manager.go index 0c14c8c9f..810b5028f 100644 --- a/pkg/rpcserver/mocks/Manager.go +++ b/pkg/rpcserver/mocks/Manager.go @@ -72,17 +72,17 @@ func (_m *Manager) CoverageFilter(modules []*vminfo.KernelModule) []uint64 { return r0 } -// MachineChecked provides a mock function with given fields: info, features, syscalls -func (_m *Manager) MachineChecked(info *flatrpc.InfoRequestRawT, features flatrpc.Feature, syscalls map[*prog.Syscall]bool) queue.Source { - ret := _m.Called(info, features, syscalls) +// MachineChecked provides a mock function with given fields: features, syscalls +func (_m *Manager) MachineChecked(features flatrpc.Feature, syscalls map[*prog.Syscall]bool) queue.Source { + ret := _m.Called(features, syscalls) if len(ret) == 0 { panic("no return value specified for MachineChecked") } var r0 queue.Source - if rf, ok := ret.Get(0).(func(*flatrpc.InfoRequestRawT, flatrpc.Feature, map[*prog.Syscall]bool) queue.Source); ok { - r0 = rf(info, features, syscalls) + if rf, ok := ret.Get(0).(func(flatrpc.Feature, map[*prog.Syscall]bool) queue.Source); ok { + r0 = rf(features, syscalls) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(queue.Source) diff --git a/pkg/rpcserver/rpcserver.go b/pkg/rpcserver/rpcserver.go index c064e6938..9d259b733 100644 --- a/pkg/rpcserver/rpcserver.go +++ b/pkg/rpcserver/rpcserver.go @@ -48,26 +48,22 @@ type Config struct { DebugTimeouts bool Procs int Slowdown int - // Extra globs that will be requested during machine checking, - // and will be passed to MachineChecked callback. - CheckGlobs []string - pcBase uint64 - localModules []*vminfo.KernelModule + pcBase uint64 + localModules []*vminfo.KernelModule } type RemoteConfig struct { *mgrconfig.Config - Manager Manager - Stats Stats - CheckGlobs []string - Debug bool + Manager Manager + Stats Stats + Debug bool } //go:generate ../../tools/mockery.sh --name Manager --output ./mocks type Manager interface { MaxSignal() signal.Signal BugFrames() (leaks []string, races []string) - MachineChecked(info *flatrpc.InfoRequest, features flatrpc.Feature, syscalls map[*prog.Syscall]bool) queue.Source + MachineChecked(features flatrpc.Feature, syscalls map[*prog.Syscall]bool) queue.Source CoverageFilter(modules []*vminfo.KernelModule) []uint64 } @@ -181,7 +177,6 @@ func New(cfg *RemoteConfig) (Server, error) { Slowdown: cfg.Timeouts.Slowdown, pcBase: pcBase, localModules: cfg.LocalModules, - CheckGlobs: cfg.CheckGlobs, }, cfg.Manager), nil } @@ -280,7 +275,6 @@ func (serv *server) handleRunnerConn(runner *Runner, conn *flatrpc.Conn) error { opts.Features = serv.setupFeatures } else { opts.Files = append(opts.Files, serv.checker.CheckFiles()...) - opts.Globs = append(serv.target.RequiredGlobs(), serv.cfg.CheckGlobs...) opts.Features = serv.cfg.Features } @@ -321,11 +315,6 @@ func (serv *server) handleMachineInfo(infoReq *flatrpc.InfoRequestRawT) (handsha serv.StatModules.Add(len(modules)) serv.canonicalModules = cover.NewCanonicalizer(modules, serv.cfg.Cover) serv.coverFilter = serv.mgr.CoverageFilter(modules) - globs := make(map[string][]string) - for _, glob := range infoReq.Globs { - globs[glob.Name] = glob.Files - } - serv.target.UpdateGlobs(globs) // Flatbuffers don't do deep copy of byte slices, // so clone manually since we pass it a goroutine. for _, file := range infoReq.Files { @@ -395,7 +384,7 @@ func (serv *server) runCheck(info *flatrpc.InfoRequest) error { } enabledFeatures := features.Enabled() serv.setupFeatures = features.NeedSetup() - newSource := serv.mgr.MachineChecked(info, enabledFeatures, enabledCalls) + newSource := serv.mgr.MachineChecked(enabledFeatures, enabledCalls) serv.baseSource.Store(newSource) serv.checkDone.Store(true) return nil diff --git a/pkg/rpcserver/runner.go b/pkg/rpcserver/runner.go index 29e79bad5..9ac1a6866 100644 --- a/pkg/rpcserver/runner.go +++ b/pkg/rpcserver/runner.go @@ -69,7 +69,6 @@ type handshakeConfig struct { LeakFrames []string RaceFrames []string Files []string - Globs []string Features flatrpc.Feature // Callback() is called in the middle of the handshake process. @@ -102,7 +101,6 @@ func (runner *Runner) Handshake(conn *flatrpc.Conn, cfg *handshakeConfig) error LeakFrames: cfg.LeakFrames, RaceFrames: cfg.RaceFrames, Files: cfg.Files, - Globs: cfg.Globs, Features: cfg.Features, } if err := flatrpc.Send(conn, connectReply); err != nil { @@ -292,7 +290,8 @@ func (runner *Runner) sendRequest(req *queue.Request) error { opts.EnvFlags |= flatrpc.ExecEnvDebug } var data []byte - if req.BinaryFile == "" { + switch req.Type { + case flatrpc.RequestTypeProgram: progData, err := req.Prog.SerializeForExec() if err != nil { // It's bad if we systematically fail to serialize programs, @@ -303,8 +302,7 @@ func (runner *Runner) sendRequest(req *queue.Request) error { return nil } data = progData - } else { - flags |= flatrpc.RequestFlagIsBinary + case flatrpc.RequestTypeBinary: fileData, err := os.ReadFile(req.BinaryFile) if err != nil { req.Done(&queue.Result{ @@ -314,6 +312,11 @@ func (runner *Runner) sendRequest(req *queue.Request) error { return nil } data = fileData + case flatrpc.RequestTypeGlob: + data = append([]byte(req.GlobPattern), 0) + flags |= flatrpc.RequestFlagReturnOutput + default: + panic("unhandled request type") } var avoid uint64 for _, id := range req.Avoid { @@ -326,8 +329,9 @@ func (runner *Runner) sendRequest(req *queue.Request) error { Type: flatrpc.HostMessagesRawExecRequest, Value: &flatrpc.ExecRequest{ Id: id, + Type: req.Type, Avoid: avoid, - ProgData: data, + Data: data, Flags: flags, ExecOpts: &opts, AllSignal: allSignal, @@ -361,7 +365,18 @@ func (runner *Runner) handleExecutingMessage(msg *flatrpc.ExecutingMessage) erro } else { runner.stats.statExecRetries.Add(1) } - runner.lastExec.Note(int(msg.Id), proc, req.Prog.Serialize(), osutil.MonotonicNano()) + var data []byte + switch req.Type { + case flatrpc.RequestTypeProgram: + data = req.Prog.Serialize() + case flatrpc.RequestTypeBinary: + data = []byte(fmt.Sprintf("executing binary %v\n", req.BinaryFile)) + case flatrpc.RequestTypeGlob: + data = []byte(fmt.Sprintf("expanding glob: %v\n", req.GlobPattern)) + default: + panic(fmt.Sprintf("unhandled request type %v", req.Type)) + } + runner.lastExec.Note(int(msg.Id), proc, data, osutil.MonotonicNano()) select { case runner.injectExec <- true: default: @@ -385,7 +400,7 @@ func (runner *Runner) handleExecResult(msg *flatrpc.ExecResult) error { } delete(runner.requests, msg.Id) delete(runner.executing, msg.Id) - if msg.Info != nil { + if req.Type == flatrpc.RequestTypeProgram && msg.Info != nil { for len(msg.Info.Calls) < len(req.Prog.Calls) { msg.Info.Calls = append(msg.Info.Calls, &flatrpc.CallInfo{ Error: 999, diff --git a/pkg/runtest/run.go b/pkg/runtest/run.go index ca3ed3b4b..d9f0aa25a 100644 --- a/pkg/runtest/run.go +++ b/pkg/runtest/run.go @@ -113,7 +113,7 @@ func (ctx *Context) Run(waitCtx context.Context) error { if !verbose || ctx.Verbose { ctx.log("%-38v: %v", req.name, result) } - if req.Request != nil && req.Request.BinaryFile != "" { + if req.Request != nil && req.Type == flatrpc.RequestTypeBinary && req.BinaryFile != "" { os.Remove(req.BinaryFile) } } @@ -400,6 +400,7 @@ func (ctx *Context) createTest(req *runRequest) { req.Request.Done(&queue.Result{}) return } + req.Type = flatrpc.RequestTypeBinary req.BinaryFile = bin ctx.submit(req) }() @@ -493,7 +494,7 @@ func checkResult(req *runRequest) error { return fmt.Errorf("non-successful result status (%v)", req.result.Status) } infos := []*flatrpc.ProgInfo{req.result.Info} - isC := req.BinaryFile != "" + isC := req.Type == flatrpc.RequestTypeBinary if isC { var err error if infos, err = parseBinOutput(req); err != nil { diff --git a/pkg/vminfo/syscalls.go b/pkg/vminfo/syscalls.go index 21ae6edd1..9793cfee8 100644 --- a/pkg/vminfo/syscalls.go +++ b/pkg/vminfo/syscalls.go @@ -57,7 +57,8 @@ func newCheckContext(ctx context.Context, cfg *Config, impl checker, executor qu } } -func (ctx *checkContext) start(fileInfos []*flatrpc.FileInfo) { +func (ctx *checkContext) do(fileInfos []*flatrpc.FileInfo, featureInfos []*flatrpc.FeatureInfo) ( + map[*prog.Syscall]bool, map[*prog.Syscall]string, Features, error) { sysTarget := targets.Get(ctx.cfg.Target.OS, ctx.cfg.Target.Arch) ctx.fs = createVirtualFilesystem(fileInfos) for _, id := range ctx.cfg.Syscalls { @@ -91,10 +92,37 @@ func (ctx *checkContext) start(fileInfos []*flatrpc.FileInfo) { }() } ctx.startFeaturesCheck() -} -func (ctx *checkContext) wait(featureInfos []*flatrpc.FeatureInfo) ( - map[*prog.Syscall]bool, map[*prog.Syscall]string, Features, error) { + var globReqs []*queue.Request + for _, glob := range ctx.target.RequiredGlobs() { + req := &queue.Request{ + Type: flatrpc.RequestTypeGlob, + GlobPattern: glob, + ExecOpts: flatrpc.ExecOpts{ + EnvFlags: ctx.cfg.Sandbox, + SandboxArg: ctx.cfg.SandboxArg, + }, + Important: true, + } + ctx.executor.Submit(req) + globReqs = append(globReqs, req) + } + + // Up to this point we submit all requests (start submitting goroutines), + // so that all requests execute in parallel. After this point we wait + // for request completion and handle results. + + globs := make(map[string][]string) + for _, req := range globReqs { + res := req.Wait(ctx.ctx) + if res.Status != queue.Success { + return nil, nil, nil, fmt.Errorf("failed to execute glob: %w (%v)\n%s\n%s", + res.Err, res.Status, req.GlobPattern, res.Output) + } + globs[req.GlobPattern] = res.GlobFiles() + } + ctx.target.UpdateGlobs(globs) + enabled := make(map[*prog.Syscall]bool) disabled := make(map[*prog.Syscall]string) for i := 0; i < ctx.pendingSyscalls; i++ { diff --git a/pkg/vminfo/vminfo.go b/pkg/vminfo/vminfo.go index d2a728585..dee1924b5 100644 --- a/pkg/vminfo/vminfo.go +++ b/pkg/vminfo/vminfo.go @@ -103,8 +103,7 @@ func (checker *Checker) Run(files []*flatrpc.FileInfo, featureInfos []*flatrpc.F map[*prog.Syscall]bool, map[*prog.Syscall]string, Features, error) { ctx := checker.checkContext checker.checkContext = nil - ctx.start(files) - return ctx.wait(featureInfos) + return ctx.do(files, featureInfos) } // Implementation of the queue.Source interface. diff --git a/pkg/vminfo/vminfo_test.go b/pkg/vminfo/vminfo_test.go index 398cf93e2..4bdccc09e 100644 --- a/pkg/vminfo/vminfo_test.go +++ b/pkg/vminfo/vminfo_test.go @@ -104,18 +104,23 @@ func createSuccessfulResults(source queue.Source, stop chan struct{}) { // Currently we have 641 (when we failed to properly dedup syscall tests, it was 4349). panic("too many test programs") } - info := &flatrpc.ProgInfo{} - for range req.Prog.Calls { - info.Calls = append(info.Calls, &flatrpc.CallInfo{ - Cover: []uint64{1}, - Signal: []uint64{1}, - Comps: []*flatrpc.Comparison{{Op1: 1, Op2: 2}}, - }) - } - req.Done(&queue.Result{ + res := &queue.Result{ Status: queue.Success, - Info: info, - }) + } + switch req.Type { + case flatrpc.RequestTypeProgram: + res.Info = &flatrpc.ProgInfo{} + for range req.Prog.Calls { + res.Info.Calls = append(res.Info.Calls, &flatrpc.CallInfo{ + Cover: []uint64{1}, + Signal: []uint64{1}, + Comps: []*flatrpc.Comparison{{Op1: 1, Op2: 2}}, + }) + } + case flatrpc.RequestTypeGlob: + res.Output = []byte("/some/file\n") + } + req.Done(res) } } |
