From fb8445ca9a36aa91aed98a02092147cb88d49d9f Mon Sep 17 00:00:00 2001 From: Taras Madan Date: Fri, 19 Jul 2024 17:06:01 +0200 Subject: syz-covermerger: store subsystems details in spanner --- tools/syz-covermerger/db.go | 68 ++++++++++++++++++++++++++++++---------- tools/syz-covermerger/init_db.sh | 12 +++++++ 2 files changed, 64 insertions(+), 16 deletions(-) mode change 100644 => 100755 tools/syz-covermerger/init_db.sh (limited to 'tools') diff --git a/tools/syz-covermerger/db.go b/tools/syz-covermerger/db.go index e0df6735f..2f347e6a7 100644 --- a/tools/syz-covermerger/db.go +++ b/tools/syz-covermerger/db.go @@ -10,6 +10,8 @@ import ( "cloud.google.com/go/spanner" "github.com/google/syzkaller/pkg/spanner/coveragedb" + "github.com/google/syzkaller/pkg/subsystem" + _ "github.com/google/syzkaller/pkg/subsystem/lists" "github.com/google/uuid" ) @@ -23,19 +25,15 @@ func saveToSpanner(ctx context.Context, projectID string, covMap map[string]*Cov } defer client.Close() + ssMatcher := subsystem.MakePathMatcher(subsystem.GetList("linux")) + ssCache := make(map[string][]string) + session := uuid.New().String() mutations := []*spanner.Mutation{} for filePath, record := range covMap { - var insert *spanner.Mutation - if insert, err = spanner.InsertOrUpdateStruct("files", &coveragedb.FilesRecord{ - Session: session, - FilePath: filePath, - Instrumented: record.Instrumented, - Covered: record.Covered, - }); err != nil { - panic(fmt.Sprintf("failed to spanner.InsertStruct(): %s", err.Error())) - } - mutations = append(mutations, insert) + mutations = append(mutations, fileRecordMutation(session, filePath, record)) + subsystems := fileSubsystems(filePath, ssMatcher, ssCache) + mutations = append(mutations, fileSubsystemsMutation(template.Namespace, filePath, subsystems)) // 80k mutations is a DB limit. 4 fields * 2k records is apx 8k mutations // let keep this value 10x lower to have a room for indexes // indexes update are also counted @@ -46,9 +44,14 @@ func saveToSpanner(ctx context.Context, projectID string, covMap map[string]*Cov mutations = nil } } + mutations = append(mutations, historyMutation(session, template, totalRows)) + if _, err = client.Apply(ctx, mutations); err != nil { + panic(fmt.Sprintf("failed to spanner.Apply(inserts): %s", err.Error())) + } +} - var historyInsert *spanner.Mutation - if historyInsert, err = spanner.InsertOrUpdateStruct("merge_history", &coveragedb.HistoryRecord{ +func historyMutation(session string, template *coveragedb.HistoryRecord, totalRows int64) *spanner.Mutation { + historyInsert, err := spanner.InsertOrUpdateStruct("merge_history", &coveragedb.HistoryRecord{ Session: session, Time: time.Now(), Namespace: template.Namespace, @@ -57,12 +60,45 @@ func saveToSpanner(ctx context.Context, projectID string, covMap map[string]*Cov Duration: template.Duration, DateTo: template.DateTo, TotalRows: totalRows, - }); err != nil { + }) + if err != nil { panic(fmt.Sprintf("failed to spanner.InsertStruct(): %s", err.Error())) } - mutations = append(mutations, historyInsert) + return historyInsert +} - if _, err = client.Apply(ctx, mutations); err != nil { - panic(fmt.Sprintf("failed to spanner.Apply(inserts): %s", err.Error())) +func fileRecordMutation(session, filePath string, record *Coverage) *spanner.Mutation { + insert, err := spanner.InsertOrUpdateStruct("files", &coveragedb.FilesRecord{ + Session: session, + FilePath: filePath, + Instrumented: record.Instrumented, + Covered: record.Covered, + }) + if err != nil { + panic(fmt.Sprintf("failed to fileRecordMutation(): %s", err.Error())) + } + return insert +} + +func fileSubsystemsMutation(ns, filePath string, subsystems []string) *spanner.Mutation { + insert, err := spanner.InsertOrUpdateStruct("file_subsystems", &coveragedb.FileSubsystems{ + Namespace: ns, + FilePath: filePath, + Subsystems: subsystems, + }) + if err != nil { + panic(fmt.Sprintf("failed to fileSubsystemsMutation(): %s", err.Error())) + } + return insert +} + +func fileSubsystems(filePath string, ssMatcher *subsystem.PathMatcher, ssCache map[string][]string) []string { + sss, cached := ssCache[filePath] + if !cached { + for _, match := range ssMatcher.Match(filePath) { + sss = append(sss, match.Name) + } + ssCache[filePath] = sss } + return sss } diff --git a/tools/syz-covermerger/init_db.sh b/tools/syz-covermerger/init_db.sh old mode 100644 new mode 100755 index f7e185221..929eaca32 --- a/tools/syz-covermerger/init_db.sh +++ b/tools/syz-covermerger/init_db.sh @@ -35,3 +35,15 @@ CREATE TABLE IF NOT EXISTS (namespace, repo, duration, dateto) );') gcloud spanner databases ddl update $db --instance=syzbot --project=syzkaller \ --ddl="$create_table" + +echo "making sure spanner table 'file_subsystems' exists" +create_table=$( echo -n ' +CREATE TABLE IF NOT EXISTS + file_subsystems ( + "namespace" text, + "filepath" text, + "subsystems" text[], + PRIMARY KEY + (namespace, filepath) );') +gcloud spanner databases ddl update $db --instance=syzbot --project=syzkaller \ + --ddl="$create_table" -- cgit mrf-deployment