// Copyright 2016 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.

// syz-crush replays crash log on multiple VMs. Usage:
//   syz-crush -config=config.file execution.log
// Intended for reproduction of particularly elusive crashes.
package main

import (
	"flag"
	"io/ioutil"
	"sync"
	"sync/atomic"
	"time"

	"github.com/google/syzkaller/pkg/instance"
	"github.com/google/syzkaller/pkg/log"
	"github.com/google/syzkaller/pkg/mgrconfig"
	"github.com/google/syzkaller/pkg/osutil"
	"github.com/google/syzkaller/pkg/report"
	"github.com/google/syzkaller/prog"
	"github.com/google/syzkaller/vm"
)

var (
	flagConfig = flag.String("config", "", "configuration file")
)

func main() {
	flag.Parse()
	cfg, err := mgrconfig.LoadFile(*flagConfig)
	if err != nil {
		log.Fatalf("%v", err)
	}
	if len(flag.Args()) != 1 {
		log.Fatalf("usage: syz-crush -config=config.file execution.log")
	}
	if _, err := prog.GetTarget(cfg.TargetOS, cfg.TargetArch); err != nil {
		log.Fatalf("%v", err)
	}
	vmPool, err := vm.Create(cfg, false)
	if err != nil {
		log.Fatalf("%v", err)
	}
	reporter, err := report.NewReporter(cfg)
	if err != nil {
		log.Fatalf("%v", err)
	}

	log.Logf(0, "booting test machines...")
	var shutdown uint32
	var wg sync.WaitGroup
	wg.Add(vmPool.Count() + 1)
	for i := 0; i < vmPool.Count(); i++ {
		i := i
		go func() {
			defer wg.Done()
			for {
				runInstance(cfg, reporter, vmPool, i)
				if atomic.LoadUint32(&shutdown) != 0 {
					break
				}
			}
		}()
	}

	shutdownC := make(chan struct{})
	osutil.HandleInterrupts(shutdownC)
	go func() {
		<-shutdownC
		wg.Done()
		atomic.StoreUint32(&shutdown, 1)
	}()
	wg.Wait()
}

func runInstance(cfg *mgrconfig.Config, reporter report.Reporter, vmPool *vm.Pool, index int) {
	inst, err := vmPool.Create(index)
	if err != nil {
		log.Logf(0, "failed to create instance: %v", err)
		return
	}
	defer inst.Close()

	execprogBin, err := inst.Copy(cfg.SyzExecprogBin)
	if err != nil {
		log.Logf(0, "failed to copy execprog: %v", err)
		return
	}
	executorBin, err := inst.Copy(cfg.SyzExecutorBin)
	if err != nil {
		log.Logf(0, "failed to copy executor: %v", err)
		return
	}
	logFile, err := inst.Copy(flag.Args()[0])
	if err != nil {
		log.Logf(0, "failed to copy log: %v", err)
		return
	}

	cmd := instance.ExecprogCmd(execprogBin, executorBin, cfg.TargetOS, cfg.TargetArch, cfg.Sandbox,
		true, true, true, cfg.Procs, -1, -1, logFile)
	outc, errc, err := inst.Run(time.Hour, nil, cmd)
	if err != nil {
		log.Logf(0, "failed to run execprog: %v", err)
		return
	}

	log.Logf(0, "vm-%v: crushing...", index)
	rep := inst.MonitorExecution(outc, errc, reporter, false)
	if rep == nil {
		// This is the only "OK" outcome.
		log.Logf(0, "vm-%v: running long enough, restarting", index)
	} else {
		f, err := ioutil.TempFile(".", "syz-crush")
		if err != nil {
			log.Logf(0, "failed to create temp file: %v", err)
			return
		}
		defer f.Close()
		log.Logf(0, "vm-%v: crashed: %v, saving to %v", index, rep.Title, f.Name())
		f.Write(rep.Output)
	}
}
