blob: 49c78c6d06d0189a2cec3608beea7d37a89e9d81 [file] [log] [blame]
// 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
}