github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/init/bgbuild.go (about) 1 // Copyright 2017 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "io/ioutil" 9 "log" 10 "os" 11 "os/exec" 12 "runtime" 13 "sort" 14 15 "github.com/u-root/u-root/pkg/cmdline" 16 ) 17 18 // Commands are built approximately in order from smallest to largest length of 19 // the command name. So, two letter commands like `ls` and `cd` will be built 20 // before `mknod` and `mount`. Generally, shorter commands are used more often 21 // (that is why they were made short) and are more likely to be used first, 22 // thus they should be built first. 23 type cmdSlice []os.FileInfo 24 25 func (p cmdSlice) Len() int { 26 return len(p) 27 } 28 29 func (p cmdSlice) Less(i, j int) bool { 30 return len(p[i].Name()) < len(p[j].Name()) 31 } 32 33 func (p cmdSlice) Swap(i, j int) { 34 p[i], p[j] = p[j], p[i] 35 } 36 37 func worker(cmds chan string) { 38 for cmdName := range cmds { 39 args := []string{"--onlybuild", "--noforce", "--lowpri", cmdName} 40 cmd := exec.Command("installcommand", args...) 41 if err := cmd.Start(); err != nil { 42 log.Println("Cannot start:", err) 43 continue 44 } 45 if err := cmd.Wait(); err != nil { 46 log.Println("installcommand error:", err) 47 } 48 } 49 } 50 51 func startBgBuild() { 52 cmds := make(chan string) 53 54 // Start a worker for each CPU. 55 for i := 0; i < runtime.NumCPU(); i++ { 56 go worker(cmds) 57 } 58 59 // Create a slice of commands and order them by the aformentioned 60 // heuristic. 61 fis, err := ioutil.ReadDir("/buildbin") 62 if err != nil { 63 log.Print(err) 64 return 65 } 66 sort.Sort(cmdSlice(fis)) 67 68 // Send the command by name to the workers. 69 for _, fi := range fis { 70 cmds <- fi.Name() 71 } 72 close(cmds) 73 } 74 75 func isBgBuildEnabled() bool { 76 return cmdline.ContainsFlag("uroot.bgbuild") 77 }