diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-06-21 17:58:12 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-06-22 16:40:45 +0200 |
| commit | c97f0d7a863bbb63de5dca44ad75c5ae7b4a154d (patch) | |
| tree | 75f9f638714eaab50b73250bdceadd860e48556b | |
| parent | 91f52697d10d451839cd60ffcd6323e99af14011 (diff) | |
pkg/build: add gvisor support
| -rw-r--r-- | pkg/build/gvisor.go | 19 | ||||
| -rw-r--r-- | pkg/osutil/osutil.go | 21 | ||||
| -rw-r--r-- | syz-ci/manager.go | 45 | ||||
| -rw-r--r-- | syz-ci/syzupdater.go | 6 |
4 files changed, 63 insertions, 28 deletions
diff --git a/pkg/build/gvisor.go b/pkg/build/gvisor.go index 8649e7e65..b96d55cf0 100644 --- a/pkg/build/gvisor.go +++ b/pkg/build/gvisor.go @@ -3,13 +3,32 @@ package build +import ( + "path/filepath" + "time" + + "github.com/google/syzkaller/pkg/osutil" +) + type gvisor struct{} func (gvisor) build(targetArch, vmType, kernelDir, outputDir, compiler, userspaceDir, cmdlineFile, sysctlFile string, config []byte) error { + if err := osutil.MkdirAll(outputDir); err != nil { + return err + } + if _, err := osutil.RunCmd(20*time.Minute, kernelDir, compiler, "build", "--verbose_failures", "--sandbox_debug", "runsc"); err != nil { + return err + } + runsc := filepath.Join(kernelDir, "bazel-bin", "runsc", "linux_amd64_pure_stripped", "runsc") + if err := osutil.CopyFile(runsc, filepath.Join(outputDir, "image")); err != nil { + return err + } + osutil.RunCmd(10*time.Minute, kernelDir, compiler, "shutdown") return nil } func (gvisor) clean(kernelDir string) error { + // Let's assume that bazel always properly handles build without cleaning (until proven otherwise). return nil } diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go index e41ad7ec1..42b65d36a 100644 --- a/pkg/osutil/osutil.go +++ b/pkg/osutil/osutil.go @@ -89,8 +89,11 @@ func IsExist(name string) bool { // FilesExist returns true if all files exist in dir. // Files are assumed to be relative names in slash notation. -func FilesExist(dir string, files []string) bool { - for _, f := range files { +func FilesExist(dir string, files map[string]bool) bool { + for f, required := range files { + if !required { + continue + } if !IsExist(filepath.Join(dir, filepath.FromSlash(f))) { return false } @@ -101,7 +104,7 @@ func FilesExist(dir string, files []string) bool { // CopyFiles copies files from srcDir to dstDir as atomically as possible. // Files are assumed to be relative names in slash notation. // All other files in dstDir are removed. -func CopyFiles(srcDir, dstDir string, files []string) error { +func CopyFiles(srcDir, dstDir string, files map[string]bool) error { // Linux does not support atomic dir replace, so we copy to tmp dir first. // Then remove dst dir and rename tmp to dst (as atomic as can get on Linux). tmpDir := dstDir + ".tmp" @@ -111,8 +114,11 @@ func CopyFiles(srcDir, dstDir string, files []string) error { if err := MkdirAll(tmpDir); err != nil { return err } - for _, f := range files { + for f, required := range files { src := filepath.Join(srcDir, filepath.FromSlash(f)) + if !required && !IsExist(src) { + continue + } dst := filepath.Join(tmpDir, filepath.FromSlash(f)) if err := MkdirAll(filepath.Dir(dst)); err != nil { return err @@ -130,15 +136,18 @@ func CopyFiles(srcDir, dstDir string, files []string) error { // LinkFiles creates hard links for files from dstDir to srcDir. // Files are assumed to be relative names in slash notation. // All other files in dstDir are removed. -func LinkFiles(srcDir, dstDir string, files []string) error { +func LinkFiles(srcDir, dstDir string, files map[string]bool) error { if err := os.RemoveAll(dstDir); err != nil { return err } if err := MkdirAll(dstDir); err != nil { return err } - for _, f := range files { + for f, required := range files { src := filepath.Join(srcDir, filepath.FromSlash(f)) + if !required && !IsExist(src) { + continue + } dst := filepath.Join(dstDir, filepath.FromSlash(f)) if err := MkdirAll(filepath.Dir(dst)); err != nil { return err diff --git a/syz-ci/manager.go b/syz-ci/manager.go index fe9808dd2..e487c35f8 100644 --- a/syz-ci/manager.go +++ b/syz-ci/manager.go @@ -30,12 +30,12 @@ import ( const kernelRebuildPeriod = syzkallerRebuildPeriod + time.Hour // List of required files in kernel build (contents of latest/current dirs). -var imageFiles = []string{ - "tag", // serialized BuildInfo - "kernel.config", // kernel config used for build - "image", // kernel image - "key", // root ssh key for the image - "obj/vmlinux", // vmlinux with debug info +var imageFiles = map[string]bool{ + "tag": true, // serialized BuildInfo + "kernel.config": false, // kernel config used for build + "image": true, // kernel image + "key": false, // root ssh key for the image + "obj/vmlinux": false, // vmlinux with debug info } // Manager represents a single syz-manager instance. @@ -52,6 +52,7 @@ type Manager struct { compilerID string syzkallerCommit string configTag string + configData []byte cfg *Config mgrcfg *ManagerConfig managercfg *mgrconfig.Config @@ -79,9 +80,11 @@ func createManager(cfg *Config, mgrcfg *ManagerConfig, stop chan struct{}) *Mana if err != nil { log.Fatal(err) } - configData, err := ioutil.ReadFile(mgrcfg.KernelConfig) - if err != nil { - log.Fatal(err) + var configData []byte + if mgrcfg.KernelConfig != "" { + if configData, err = ioutil.ReadFile(mgrcfg.KernelConfig); err != nil { + log.Fatal(err) + } } syzkallerCommit, _ := readTag(filepath.FromSlash("syzkaller/current/tag")) if syzkallerCommit == "" { @@ -105,6 +108,7 @@ func createManager(cfg *Config, mgrcfg *ManagerConfig, stop chan struct{}) *Mana compilerID: compilerID, syzkallerCommit: syzkallerCommit, configTag: hash.String(configData), + configData: configData, cfg: cfg, mgrcfg: mgrcfg, managercfg: managercfg, @@ -263,16 +267,12 @@ func (mgr *Manager) build() error { if err := osutil.MkdirAll(tmpDir); err != nil { return fmt.Errorf("failed to create tmp dir: %v", err) } - kernelConfigData, err := ioutil.ReadFile(mgr.mgrcfg.KernelConfig) - if err != nil { - return err - } if err := config.SaveFile(filepath.Join(tmpDir, "tag"), info); err != nil { return fmt.Errorf("failed to write tag file: %v", err) } if err := build.Image(mgr.managercfg.TargetOS, mgr.managercfg.TargetVMArch, mgr.managercfg.Type, mgr.kernelDir, tmpDir, mgr.mgrcfg.Compiler, mgr.mgrcfg.Userspace, - mgr.mgrcfg.KernelCmdline, mgr.mgrcfg.KernelSysctl, kernelConfigData); err != nil { + mgr.mgrcfg.KernelCmdline, mgr.mgrcfg.KernelSysctl, mgr.configData); err != nil { if _, ok := err.(build.KernelBuildError); ok { rep := &report.Report{ Title: fmt.Sprintf("%v build error", mgr.mgrcfg.RepoAlias), @@ -420,7 +420,9 @@ func (mgr *Manager) createTestConfig(imageDir string, info *BuildInfo) (*mgrconf mgrcfg.Tag = info.KernelCommit mgrcfg.Workdir = filepath.Join(imageDir, "workdir") mgrcfg.Image = filepath.Join(imageDir, "image") - mgrcfg.SSHKey = filepath.Join(imageDir, "key") + if keyFile := filepath.Join(imageDir, "key"); osutil.IsExist(keyFile) { + mgrcfg.SSHKey = keyFile + } mgrcfg.KernelObj = filepath.Join(imageDir, "obj") mgrcfg.KernelSrc = mgr.kernelDir if err := mgrconfig.Complete(mgrcfg); err != nil { @@ -451,7 +453,9 @@ func (mgr *Manager) writeConfig(buildTag string) (string, error) { // problems, we need to make a copy of sources after build. mgrcfg.KernelSrc = mgr.kernelDir mgrcfg.Image = filepath.Join(mgr.currentDir, "image") - mgrcfg.SSHKey = filepath.Join(mgr.currentDir, "key") + if keyFile := filepath.Join(mgr.currentDir, "key"); osutil.IsExist(keyFile) { + mgrcfg.SSHKey = keyFile + } if err := mgrconfig.Complete(mgrcfg); err != nil { return "", fmt.Errorf("bad manager config: %v", err) } @@ -490,9 +494,12 @@ func (mgr *Manager) uploadBuild(info *BuildInfo, imageDir string) (string, error } func (mgr *Manager) createDashboardBuild(info *BuildInfo, imageDir, typ string) (*dashapi.Build, error) { - kernelConfig, err := ioutil.ReadFile(filepath.Join(imageDir, "kernel.config")) - if err != nil { - return nil, fmt.Errorf("failed to read kernel.config: %v", err) + var kernelConfig []byte + if kernelConfigFile := filepath.Join(imageDir, "kernel.config"); osutil.IsExist(kernelConfigFile) { + var err error + if kernelConfig, err = ioutil.ReadFile(kernelConfigFile); err != nil { + return nil, fmt.Errorf("failed to read kernel.config: %v", err) + } } // Resulting build depends on both kernel build tag and syzkaller commmit. // Also mix in build type, so that image error builds are not merged into normal builds. diff --git a/syz-ci/syzupdater.go b/syz-ci/syzupdater.go index 4df6337ff..d1f9842ef 100644 --- a/syz-ci/syzupdater.go +++ b/syz-ci/syzupdater.go @@ -38,7 +38,7 @@ type SyzUpdater struct { syzkallerDir string latestDir string currentDir string - syzFiles []string + syzFiles map[string]bool targets map[string]bool } @@ -82,9 +82,9 @@ func NewSyzUpdater(cfg *Config) *SyzUpdater { files[fmt.Sprintf("bin/%v_%v/syz-execprog", os, vmarch)] = true files[fmt.Sprintf("bin/%v_%v/syz-executor", os, arch)] = true } - var syzFiles []string + syzFiles := make(map[string]bool) for f := range files { - syzFiles = append(syzFiles, f) + syzFiles[f] = true } return &SyzUpdater{ |
