diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-09-12 14:45:40 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-09-12 15:15:27 +0000 |
| commit | aa0392c8b3d691caa48ae4797d566c9dd3ba33c3 (patch) | |
| tree | 1c4d6e23fa72687c2f5c20a6c7be8d37efac649c /syz-hub/state | |
| parent | 747460a298ce749bbd145032513b370ae24ff897 (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.go | 45 |
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 } |
