syzkaller/pkg/build/openbsd.go
Dmitry Vyukov 9633c5c8a1 pkg/build: extract bazel build errors
We currently manually call extractRootCause in few selected places
to denote kernel build errors that we want to report to developers.
The rest are considered infra errors that we don't report.
This does not work well. We are missing fuchsia and gvisor build errors.
Treat all external command exection failures as kernel build errors instead.
Let's see how this works in practice.
Also add bazel-specfic error patterns and tests.
2019-03-29 11:00:34 +01:00

102 lines
3.2 KiB
Go

// Copyright 2018 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package build
import (
"fmt"
"path/filepath"
"runtime"
"strconv"
"time"
"github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/pkg/osutil"
)
type openbsd struct{}
func (ctx openbsd) build(targetArch, vmType, kernelDir, outputDir, compiler, userspaceDir,
cmdlineFile, sysctlFile string, config []byte) error {
const kernelName = "SYZKALLER"
confDir := fmt.Sprintf("%v/sys/arch/%v/conf", kernelDir, targetArch)
compileDir := fmt.Sprintf("%v/sys/arch/%v/compile/%v", kernelDir, targetArch, kernelName)
if err := osutil.WriteFile(filepath.Join(confDir, kernelName), config); err != nil {
return err
}
if err := osutil.MkdirAll(compileDir); err != nil {
return err
}
makefile := []byte(".include \"../Makefile.inc\"\n")
if err := osutil.WriteFile(filepath.Join(compileDir, "Makefile"), makefile); err != nil {
return err
}
for _, tgt := range []string{"clean", "obj", "config", "all"} {
if err := ctx.make(compileDir, tgt); err != nil {
return err
}
}
for _, s := range []struct{ dir, src, dst string }{
{compileDir, "obj/bsd", "kernel"},
{compileDir, "obj/bsd.gdb", "obj/bsd.gdb"},
{userspaceDir, "image", "image"},
{userspaceDir, "key", "key"},
} {
fullSrc := filepath.Join(s.dir, s.src)
fullDst := filepath.Join(outputDir, s.dst)
if err := osutil.CopyFile(fullSrc, fullDst); err != nil {
return fmt.Errorf("failed to copy %v -> %v: %v", fullSrc, fullDst, err)
}
}
if vmType == "gce" {
return ctx.copyFilesToImage(
filepath.Join(userspaceDir, "overlay"), outputDir)
}
return nil
}
func (ctx openbsd) clean(kernelDir, targetArch string) error {
// Building clean is fast enough and incremental builds in face of
// changing config files don't work. Instead of optimizing for the
// case where humans have to think, let's bludgeon it with a
// machine.
return nil
}
func (ctx openbsd) make(kernelDir string, args ...string) error {
args = append([]string{"-j", strconv.Itoa(runtime.NumCPU())}, args...)
_, err := osutil.RunCmd(10*time.Minute, kernelDir, "make", args...)
return err
}
// copyFilesToImage populates the filesystem image in outputDir with
// run-specific files. The kernel is copied as /bsd and if overlayDir
// exists, its contents are copied into corresponding files in the
// image.
//
// Ideally a user space tool capable of understanding FFS should
// interpret FFS inside the image file, but vnd(4) device would do in
// a pinch.
func (ctx openbsd) copyFilesToImage(overlayDir, outputDir string) error {
script := fmt.Sprintf(`set -eux
OVERLAY="%s"
# Cleanup in case something failed before.
doas umount /altroot || true
doas vnconfig -u vnd0 || true
doas /sbin/vnconfig vnd0 image
doas mount /dev/vnd0a /altroot
doas cp kernel /altroot/bsd
test -d "$OVERLAY" && doas cp -Rf "$OVERLAY"/. /altroot
doas umount /altroot
doas vnconfig -u vnd0
`, overlayDir)
debugOut, err := osutil.RunCmd(10*time.Minute, outputDir, "/bin/sh", "-c", script)
if err != nil {
log.Logf(0, "Error copying kernel into image %v\n%v\n", outputDir, debugOut)
}
return err
}