github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/subsystem/entities.go (about) 1 // Copyright 2023 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 subsystem 5 6 type Subsystem struct { 7 Name string 8 PathRules []PathRule 9 Syscalls []string 10 Lists []string 11 Maintainers []string 12 Parents []*Subsystem 13 // If NoReminders is true, there should be no monthly reports for the subsystem. 14 NoReminders bool 15 // If NoIndirectCc is true, the subsystem lists are not tagged in sub-subsystem reports. 16 NoIndirectCc bool 17 } 18 19 // ReachableParents returns the set of subsystems reachable from the current one. 20 func (subsystem *Subsystem) ReachableParents() map[*Subsystem]struct{} { 21 ret := make(map[*Subsystem]struct{}) 22 var dfs func(node *Subsystem) 23 dfs = func(node *Subsystem) { 24 for _, p := range node.Parents { 25 if p == subsystem { 26 panic("loop in the parents relation") 27 } 28 if _, visited := ret[p]; !visited { 29 ret[p] = struct{}{} 30 dfs(p) 31 } 32 } 33 } 34 dfs(subsystem) 35 return ret 36 } 37 38 // Emails returns the list of emails related to the subsystem. 39 func (subsystem *Subsystem) Emails() []string { 40 ret := []string{} 41 // For the subsystem itself, we take both lists and maintainers. 42 ret = append(ret, subsystem.Lists...) 43 ret = append(ret, subsystem.Maintainers...) 44 // For its parent subsystems, we only take lists. 45 for parent := range subsystem.ReachableParents() { 46 if !parent.NoIndirectCc { 47 ret = append(ret, parent.Lists...) 48 } 49 } 50 return ret 51 } 52 53 func FilterList(list []*Subsystem, filter func(*Subsystem) bool) []*Subsystem { 54 keep := map[*Subsystem]bool{} 55 for _, item := range list { 56 keep[item] = filter(item) 57 } 58 newList := []*Subsystem{} 59 for _, item := range list { 60 if !keep[item] { 61 continue 62 } 63 newParents := []*Subsystem{} 64 for _, p := range item.Parents { 65 if keep[p] { 66 newParents = append(newParents, p) 67 } 68 } 69 item.Parents = newParents 70 newList = append(newList, item) 71 } 72 return newList 73 } 74 75 // PathRule describes the part of the directory tree belonging to a single subsystem. 76 type PathRule struct { 77 IncludeRegexp string 78 // ExcludeRegexps are tested before IncludeRegexp. 79 ExcludeRegexp string 80 } 81 82 func (pr *PathRule) IsEmpty() bool { 83 return pr.IncludeRegexp == "" && pr.ExcludeRegexp == "" 84 }