aboutsummaryrefslogtreecommitdiffstats
path: root/syz-hub/state
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-09-12 14:45:40 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-09-12 15:15:27 +0000
commitaa0392c8b3d691caa48ae4797d566c9dd3ba33c3 (patch)
tree1c4d6e23fa72687c2f5c20a6c7be8d37efac649c /syz-hub/state
parent747460a298ce749bbd145032513b370ae24ff897 (diff)
syz-hub: purse inactive managers
Discard manager data after 30 days of inactivity. This should automatically get rid of decomissioned managers, and old manual instances.
Diffstat (limited to 'syz-hub/state')
-rw-r--r--syz-hub/state/state.go45
1 files changed, 45 insertions, 0 deletions
diff --git a/syz-hub/state/state.go b/syz-hub/state/state.go
index 37bdb2b59..4d25c20a3 100644
--- a/syz-hub/state/state.go
+++ b/syz-hub/state/state.go
@@ -9,6 +9,7 @@ import (
"path/filepath"
"sort"
"strconv"
+ "strings"
"time"
"github.com/google/syzkaller/pkg/db"
@@ -34,6 +35,7 @@ type State struct {
// Manager represents one syz-manager instance.
type Manager struct {
name string
+ dir string
Domain string
corpusSeq uint64
reproSeq uint64
@@ -77,11 +79,17 @@ func Make(dir string) (*State, error) {
return nil, fmt.Errorf("failed to read %v dir: %w", managersDir, err)
}
for _, manager := range managers {
+ if strings.HasSuffix(manager.Name(), purgedSuffix) {
+ continue
+ }
_, err := st.createManager(manager.Name())
if err != nil {
return nil, err
}
}
+ if err := st.PurgeOldManagers(); err != nil {
+ return nil, err
+ }
log.Logf(0, "purging corpus...")
st.purgeCorpus()
log.Logf(0, "done, %v programs", len(st.Corpus.Records))
@@ -141,6 +149,7 @@ func (st *State) createManager(name string) (*Manager, error) {
osutil.MkdirAll(dir)
mgr := &Manager{
name: name,
+ dir: dir,
corpusFile: filepath.Join(dir, "corpus.db"),
corpusSeqFile: filepath.Join(dir, "seq"),
reproSeqFile: filepath.Join(dir, "repro.seq"),
@@ -171,6 +180,40 @@ func (st *State) createManager(name string) (*Manager, error) {
return mgr, nil
}
+const purgedSuffix = ".purged"
+
+func (st *State) PurgeOldManagers() error {
+ const (
+ timeDay = 24 * time.Hour
+ purgePeriod = 30 * timeDay
+ )
+ purgedSomething := false
+ for _, mgr := range st.Managers {
+ info, err := os.Stat(mgr.corpusSeqFile)
+ if err != nil {
+ return err
+ }
+ if time.Since(info.ModTime()) < purgePeriod {
+ continue
+ }
+ log.Logf(0, "purging manager %v as it was inactive for %v days", mgr.name, int(purgePeriod/timeDay))
+ oldDir := mgr.dir + purgedSuffix
+ os.RemoveAll(oldDir)
+ if err := os.Rename(mgr.dir, oldDir); err != nil {
+ return err
+ }
+ delete(st.Managers, mgr.name)
+ purgedSomething = true
+ }
+ if !purgedSomething {
+ return nil
+ }
+ corpus := len(st.Corpus.Records)
+ st.purgeCorpus()
+ log.Logf(0, "reduced corpus from %v to %v programs", corpus, len(st.Corpus.Records))
+ return nil
+}
+
func (st *State) Connect(name, domain string, fresh bool, calls []string, corpus [][]byte) error {
mgr := st.Managers[name]
if mgr == nil {
@@ -226,6 +269,8 @@ func (st *State) Sync(name string, add [][]byte, del []string) (string, []rpctyp
mgr.Added += len(add)
mgr.Deleted += len(del)
mgr.New += len(progs)
+ // Update seq file b/c PurgeOldManagers looks at it to detect inactive managers.
+ saveSeqFile(mgr.corpusSeqFile, mgr.corpusSeq)
return mgr.Domain, progs, more, err
}