func initGCE() { var err error GCE, err = gce.NewContext() if err != nil { Fatalf("failed to init gce: %v", err) } Logf(0, "gce initialized: running on %v, internal IP %v, project %v, zone %v", GCE.Instance, GCE.InternalIP, GCE.ProjectID, GCE.ZoneID) }
func main() { flag.Parse() cfg = readConfig(*flagConfig) EnableLogCaching(1000, 1<<20) initHttp(fmt.Sprintf(":%v", cfg.Http_Port)) gopath, err := filepath.Abs("gopath") if err != nil { Fatalf("failed to get absolute path: %v", err) } os.Setenv("GOPATH", gopath) ctx = context.Background() storageClient, err = storage.NewClient(ctx) if err != nil { Fatalf("failed to create cloud storage client: %v", err) } GCE, err = gce.NewContext() if err != nil { Fatalf("failed to init gce: %v", err) } Logf(0, "gce initialized: running on %v, internal IP, %v project %v, zone %v", GCE.Instance, GCE.InternalIP, GCE.ProjectID, GCE.ZoneID) sigC := make(chan os.Signal, 2) signal.Notify(sigC, syscall.SIGINT, syscall.SIGUSR1) var managerCmd *exec.Cmd managerStopped := make(chan error) stoppingManager := false var lastImageUpdated time.Time var lastSyzkallerHash string var delayDuration time.Duration for { if delayDuration != 0 { Logf(0, "sleep for %v", delayDuration) select { case <-time.After(delayDuration): case err := <-managerStopped: if managerCmd == nil { Fatalf("spurious manager stop signal") } Logf(0, "syz-manager exited with %v", err) managerCmd = nil atomic.StoreUint32(&managerHttpPort, 0) case s := <-sigC: switch s { case syscall.SIGUSR1: // just poll for updates Logf(0, "SIGUSR1") case syscall.SIGINT: Logf(0, "SIGINT") if managerCmd != nil { Logf(0, "shutting down syz-manager...") managerCmd.Process.Signal(syscall.SIGINT) select { case err := <-managerStopped: if managerCmd == nil { Fatalf("spurious manager stop signal") } Logf(0, "syz-manager exited with %v", err) case <-sigC: managerCmd.Process.Kill() case <-time.After(time.Minute): managerCmd.Process.Kill() } } os.Exit(0) } } } delayDuration = 10 * time.Minute // assume that an error happened imageArchive, imageUpdated, err := openFile(cfg.Image_Archive) if err != nil { Logf(0, "%v", err) continue } syzkallerHash, err := updateSyzkallerBuild() if err != nil { Logf(0, "failed to update syzkaller: %v", err) continue } Logf(0, "image update time %v, syzkaller hash %v", imageUpdated, syzkallerHash) if lastImageUpdated == imageUpdated && lastSyzkallerHash == syzkallerHash && managerCmd != nil { delayDuration = time.Hour continue } if managerCmd != nil { if !stoppingManager { stoppingManager = true Logf(0, "stopping syz-manager...") managerCmd.Process.Signal(syscall.SIGINT) } else { Logf(0, "killing syz-manager...") managerCmd.Process.Kill() } delayDuration = time.Minute continue } if !*flagNoImageCreate && lastImageUpdated != imageUpdated { Logf(0, "downloading image archive...") if err := os.RemoveAll("image"); err != nil { Logf(0, "failed to remove image dir: %v", err) continue } if err := downloadAndExtract(imageArchive, "image"); err != nil { Logf(0, "failed to download and extract %v: %v", cfg.Image_Archive, err) continue } Logf(0, "uploading image...") if err := uploadFile("image/disk.tar.gz", cfg.Image_Path); err != nil { Logf(0, "failed to upload image: %v", err) continue } Logf(0, "creating gce image...") if err := GCE.DeleteImage(cfg.Image_Name); err != nil { Logf(0, "failed to delete GCE image: %v", err) continue } if err := GCE.CreateImage(cfg.Image_Name, cfg.Image_Path); err != nil { Logf(0, "failed to create GCE image: %v", err) continue } } *flagNoImageCreate = false lastImageUpdated = imageUpdated if !*flagNoRebuild && lastSyzkallerHash != syzkallerHash { Logf(0, "building syzkaller...") if err := buildSyzkaller(); err != nil { Logf(0, "failed to update/build syzkaller: %v", err) continue } } *flagNoRebuild = false lastSyzkallerHash = syzkallerHash port, err := chooseUnusedPort() if err != nil { Logf(0, "failed to choose an unused port: %v", err) continue } if err := writeManagerConfig(port, "manager.cfg"); err != nil { Logf(0, "failed to write manager config: %v", err) continue } Logf(0, "starting syz-manager (image %v, syzkaller %v)...", lastImageUpdated, lastSyzkallerHash) managerCmd = exec.Command("gopath/src/github.com/google/syzkaller/bin/syz-manager", "-config=manager.cfg") if err := managerCmd.Start(); err != nil { Logf(0, "failed to start syz-manager: %v", err) managerCmd = nil continue } stoppingManager = false atomic.StoreUint32(&managerHttpPort, uint32(port)) go func() { managerStopped <- managerCmd.Wait() }() delayDuration = time.Hour } }