github.com/andrewsun2898/u-root@v6.0.1-0.20200616011413-4b2895c1b815+incompatible/cmds/core/init/init.go (about) 1 // Copyright 2012-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 // init is u-root's standard userspace init process. 6 // 7 // init is intended to be the first process run by the kernel when it boots up. 8 // init does some basic initialization (mount file systems, turn on loopback) 9 // and then tries to execute, in order, /inito, a uinit (either in /bin, /bbin, 10 // or /ubin), and then a shell (/bin/defaultsh and /bin/sh). 11 package main 12 13 import ( 14 "flag" 15 "fmt" 16 "io/ioutil" 17 "log" 18 "os/exec" 19 "syscall" 20 21 "github.com/u-root/u-root/pkg/cmdline" 22 "github.com/u-root/u-root/pkg/libinit" 23 "github.com/u-root/u-root/pkg/uflag" 24 "github.com/u-root/u-root/pkg/ulog" 25 ) 26 27 var ( 28 verbose = flag.Bool("v", false, "print all build commands") 29 test = flag.Bool("test", false, "Test mode: don't try to set control tty") 30 debug = func(string, ...interface{}) {} 31 osInitGo = func() {} 32 ) 33 34 func main() { 35 flag.Parse() 36 37 log.Printf("Welcome to u-root!") 38 fmt.Println(` _`) 39 fmt.Println(` _ _ _ __ ___ ___ | |_`) 40 fmt.Println(` | | | |____| '__/ _ \ / _ \| __|`) 41 fmt.Println(` | |_| |____| | | (_) | (_) | |_`) 42 fmt.Println(` \__,_| |_| \___/ \___/ \__|`) 43 fmt.Println() 44 45 log.SetPrefix("init: ") 46 47 if *verbose { 48 debug = log.Printf 49 } 50 51 // Before entering an interactive shell, decrease the loglevel because 52 // spamming non-critical logs onto the shell frustrates users. The logs 53 // are still accessible through dmesg. 54 if !*verbose { 55 // Only messages more severe than "notice" are printed. 56 if err := ulog.KernelLog.SetConsoleLogLevel(ulog.KLogNotice); err != nil { 57 log.Printf("Could not set log level: %v", err) 58 } 59 } 60 61 libinit.SetEnv() 62 libinit.CreateRootfs() 63 libinit.NetInit() 64 65 // Potentially exec systemd if we have been asked to. 66 osInitGo() 67 68 // Start background build. 69 if isBgBuildEnabled() { 70 go startBgBuild() 71 } 72 73 // Turn off job control when test mode is on. 74 ctty := libinit.WithTTYControl(!*test) 75 76 // Allows passing args to uinit via kernel parameters, for example: 77 // 78 // uroot.uinitargs="-v --foobar" 79 // 80 // We also allow passing args to uinit via a flags file in 81 // /etc/uinit.flags. 82 args := cmdline.GetUinitArgs() 83 if contents, err := ioutil.ReadFile("/etc/uinit.flags"); err == nil { 84 args = append(args, uflag.FileToArgv(string(contents))...) 85 } 86 uinitArgs := libinit.WithArguments(args...) 87 88 cmdList := []*exec.Cmd{ 89 // inito is (optionally) created by the u-root command when the 90 // u-root initramfs is merged with an existing initramfs that 91 // has a /init. The name inito means "original /init" There may 92 // be an inito if we are building on an existing initramfs. All 93 // initos need their own pid space. 94 libinit.Command("/inito", libinit.WithCloneFlags(syscall.CLONE_NEWPID), ctty), 95 96 libinit.Command("/bbin/uinit", ctty, uinitArgs), 97 libinit.Command("/bin/uinit", ctty, uinitArgs), 98 libinit.Command("/buildbin/uinit", ctty, uinitArgs), 99 100 libinit.Command("/bin/defaultsh", ctty), 101 libinit.Command("/bin/sh", ctty), 102 } 103 104 cmdCount := libinit.RunCommands(debug, cmdList...) 105 if cmdCount == 0 { 106 log.Printf("No suitable executable found in %v", cmdList) 107 } 108 109 // We need to reap all children before exiting. 110 log.Printf("Waiting for orphaned children") 111 libinit.WaitOrphans() 112 log.Printf("All commands exited") 113 log.Printf("Syncing filesystems") 114 syscall.Sync() 115 log.Printf("Exiting...") 116 }