diff --git a/.gitignore b/.gitignore index e9e0554ec..566b89dfe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ nocontent.efi linux-stable linux-firmware vboot_reference +vboot config.txt newKern usb/usb @@ -24,4 +25,4 @@ upspin/ etc/ # we install binaries into usr/bin, ignore it. -usr/bin/ +rootfs/usr/bin/ diff --git a/cmds/uinit/root_linux.go b/cmds/uinit/root_linux.go new file mode 100644 index 000000000..fbcc3d908 --- /dev/null +++ b/cmds/uinit/root_linux.go @@ -0,0 +1,130 @@ +// Copyright 2014-2017 the u-root Authors. All rights reserved +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package util contains various u-root utility functions. +package main + +import ( + "fmt" + "io/ioutil" + "os" + "runtime" + "syscall" + + "github.com/u-root/u-root/pkg/ulog" + "golang.org/x/sys/unix" +) + +const ( + // Not all these paths may be populated or even exist but OTOH they might. + PATHHEAD = "/ubin" + PATHMID = "/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin:/usr/local/sbin" + PATHTAIL = "/buildbin:/bbin" +) + +type Creator interface { + Create() error + fmt.Stringer +} + +type Dir struct { + Name string + Mode os.FileMode +} + +func (d Dir) Create() error { + return os.MkdirAll(d.Name, d.Mode) +} + +func (d Dir) String() string { + return fmt.Sprintf("dir %q (mode %#o)", d.Name, d.Mode) +} + +type File struct { + Name string + Contents string + Mode os.FileMode +} + +func (f File) Create() error { + return ioutil.WriteFile(f.Name, []byte(f.Contents), f.Mode) +} + +func (f File) String() string { + return fmt.Sprintf("file %q (mode %#o)", f.Name, f.Mode) +} + +type Symlink struct { + Target string + NewPath string +} + +func (s Symlink) Create() error { + os.Remove(s.NewPath) + return os.Symlink(s.Target, s.NewPath) +} + +func (s Symlink) String() string { + return fmt.Sprintf("symlink %q -> %q", s.NewPath, s.Target) +} + +type Link struct { + OldPath string + NewPath string +} + +func (s Link) Create() error { + os.Remove(s.NewPath) + return os.Link(s.OldPath, s.NewPath) +} + +func (s Link) String() string { + return fmt.Sprintf("link %q -> %q", s.NewPath, s.OldPath) +} + +type Dev struct { + Name string + Mode uint32 + Dev int +} + +func (d Dev) Create() error { + os.Remove(d.Name) + return syscall.Mknod(d.Name, d.Mode, d.Dev) +} + +func (d Dev) String() string { + return fmt.Sprintf("dev %q (mode %#o; magic %d)", d.Name, d.Mode, d.Dev) +} + +type Mount struct { + Source string + Target string + FSType string + Flags uintptr + Opts string +} + +func (m Mount) Create() error { + return syscall.Mount(m.Source, m.Target, m.FSType, m.Flags, m.Opts) +} + +func (m Mount) String() string { + return fmt.Sprintf("mount -t %q -o %s %q %q flags %#x", m.FSType, m.Opts, m.Source, m.Target, m.Flags) +} + +func GoBin() string { + return fmt.Sprintf("/go/bin/%s_%s:/go/bin:/go/pkg/tool/%s_%s", runtime.GOOS, runtime.GOARCH, runtime.GOOS, runtime.GOARCH) +} + +func create(namespace []Creator) { + // Clear umask bits so that we get stuff like ptmx right. + m := unix.Umask(0) + defer unix.Umask(m) + for _, c := range namespace { + if err := c.Create(); err != nil { + ulog.KernelLog.Printf("u-root init: error creating %s: %v", c, err) + } + } +} diff --git a/cmds/uinit/uinit.go b/cmds/uinit/uinit.go index 433d799d3..725d023dc 100644 --- a/cmds/uinit/uinit.go +++ b/cmds/uinit/uinit.go @@ -4,13 +4,10 @@ // This is the basic chromebook uinit. -// +build go1.11 - package main import ( "fmt" - flag "github.com/spf13/pflag" "io" "io/ioutil" "log" @@ -21,9 +18,10 @@ import ( "syscall" "time" + flag "github.com/spf13/pflag" + "github.com/u-root/u-root/pkg/cpio" "github.com/u-root/u-root/pkg/mount/gpt" - "github.com/u-root/u-root/pkg/uroot/util" ) // For now we are going to stick with a single @@ -157,23 +155,18 @@ func x11(n string, args ...string) error { // The tmp is particularly useful as it avoids races between root-owned files and files // for this user. var ( - namespace = []util.Creator{ - util.Mount{Source: "tmpfs", Target: "/go/pkg/linux_amd64", FSType: "tmpfs"}, - util.Mount{Source: "tmpfs", Target: "/dev/shm", FSType: "tmpfs"}, - util.Mount{Source: "tmpfs", Target: "/ubin", FSType: "tmpfs"}, - util.Mount{Source: "tmpfs", Target: "/pkg", FSType: "tmpfs"}, - } - rootFileSystem = []util.Creator{ - util.Dir{Name: "/go/pkg/linux_amd64", Mode: 0777}, - util.Dir{Name: "/dev/shm", Mode: 0777}, - util.Dir{Name: "/pkg", Mode: 0777}, - util.Dir{Name: "/ubin", Mode: 0777}, + namespace = []Creator{ + Mount{Source: "tmpfs", Target: "/dev/shm", FSType: "tmpfs"}, + } + rootFileSystem = []Creator{ + Dir{Name: "/go/pkg/linux_amd64", Mode: 0777}, + Dir{Name: "/dev/shm", Mode: 0777}, + Dir{Name: "/pkg", Mode: 0777}, + Dir{Name: "/ubin", Mode: 0777}, // fusermount requires this. When we write our own we can remove this. - util.Symlink{NewPath: "/etc/mtab", Target: "/proc/mounts"}, - // Sigh. - util.Symlink{NewPath: "/bin/sh", Target: "/bin/bash"}, + Symlink{NewPath: "/etc/mtab", Target: "/proc/mounts"}, // Resolve localhost name - util.File{Name: "/etc/hosts", Contents: "127.0.0.1\tlocalhost\n::1\tlocalhost ip6-localhost ip6-loopback\n", Mode: 0644}, + File{Name: "/etc/hosts", Contents: "127.0.0.1\tlocalhost\n::1\tlocalhost ip6-localhost ip6-loopback\n", Mode: 0644}, } ) @@ -370,50 +363,6 @@ func main() { log.Printf("tczSetup: %v", err) } - // buildbin was not populated, potentially, so we have to do it again. - c, err := filepath.Glob("/src/github.com/u-root/*/cmds/*/[a-z]*") - if err != nil || len(c) == 0 { - log.Printf("In a break with tradition, you seem to have NO u-root commands: %v", err) - } - o, err := filepath.Glob("/src/*/*/*") - if err != nil { - log.Printf("Your filepath glob for other commands seems busted: %v", err) - } - c = append(c, o...) - for _, v := range c { - name := filepath.Base(v) - if name == "installcommand" || name == "init" { - continue - } else { - destPath := filepath.Join("/buildbin", name) - source := "/buildbin/installcommand" - if err := os.Symlink(source, destPath); err != nil { - log.Printf("Symlink %v -> %v failed; %v", source, destPath, err) - } - } - } - - a := []string{"build"} - envs := os.Environ() - debug("envs %v", envs) - //os.Setenv("GOBIN", "/buildbin") - // util.CmdsPath vanished - //a = append(a, "-o", "/buildbin/installcommand", filepath.Join(util.CmdsPath, "installcommand")) - a = append(a, "-o", "/buildbin/installcommand", "github.com/u-root/u-root/cmds/core/installcommand") - icmd := exec.Command("go", a...) - installenvs := envs - installenvs = append(envs, "GOBIN=/buildbin") - icmd.Env = installenvs - icmd.Dir = "/" - - icmd.Stdin = os.Stdin - icmd.Stderr = os.Stderr - icmd.Stdout = os.Stdout - debug("Run %v", icmd) - if err := icmd.Run(); err != nil { - log.Printf("%v\n", err) - } - cmd := exec.Command("ip", "addr", "add", "127.0.0.1/24", "lo") if o, err := cmd.CombinedOutput(); err != nil { log.Printf("ip link failed(%v, %v); continuing", string(o), err) diff --git a/usb/tczlist.go b/usb/tczlist.go index 8c6082985..10b48b0b3 100644 --- a/usb/tczlist.go +++ b/usb/tczlist.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.11 +// +build go1.17 package main diff --git a/usb/urootlist.go b/usb/urootlist.go index 9c9646716..84adfbd94 100644 --- a/usb/urootlist.go +++ b/usb/urootlist.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.11 - package main var ( diff --git a/usb/usb.go b/usb/usb.go index 9b2cf1a0f..a7c2e78c7 100644 --- a/usb/usb.go +++ b/usb/usb.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.11 - package main //include a loading bar @@ -191,9 +189,9 @@ func goGet() error { func goBuildStatic() error { oFile := filepath.Join(workingDir, "linux-stable", initramfs) - n, err := filepath.Glob("../u-root/cmds/core/*") + n, err := filepath.Glob("../u-root/cmds/[ce]*/*") if err != nil { - return fmt.Errorf("../u-root/cmds/core/*: %v", err) + return fmt.Errorf("../u-root/cmds/[ce]/*: %v", err) } args := append([]string{"-o", oFile}, n...) cmd := exec.Command("u-root", append(args, staticCmdList...)...) @@ -205,24 +203,14 @@ func goBuildStatic() error { return nil } +// A new change: we no longer need to add u-root to this partition, +// as we build it all for the "static" case. func goBuildDynamic() error { - args := []string{"-o", filepath.Join(workingDir, initramfs)} - for _, v := range []string{"usr", "lib", "tcz", "etc", "upspin", ".ssh"} { - if _, err := os.Stat(v); err != nil { - continue - } - args = append(args, "-files", filepath.Join(workingDir, v)+":"+v) - } + args := []string{"-o", filepath.Join(workingDir, initramfs), "-nocmd", "-files", "rootfs:", "-files", "/usr/bin/bash", "-base", "/dev/null"} log.Print("WARNING: skipping pkg/sos/html; fix me") if false { args = append(args, "-files", "pkg/sos/html:etc/sos/html") } - args = append(args, dynamicCmdList...) - n, err := filepath.Glob("../u-root/cmds/*/*") - if err != nil { - return fmt.Errorf("../u-root/cmds/*/*: %v", err) - } - args = append(args, n...) log.Printf("Run u-root with args %v", args) cmd := exec.Command("u-root", args...) cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr @@ -239,7 +227,7 @@ func getSUIDbinaries() error { } binaries := []string{"/bin/fusermount"} for _, b := range binaries { - cmd := exec.Command("sudo", "rsync", "-av", b, "usr/bin/") + cmd := exec.Command("sudo", "rsync", "-av", b, "rootfs/usr/bin/") cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr cmd.Env = os.Environ() if err := cmd.Run(); err != nil { @@ -346,14 +334,21 @@ func installUrootGpt() error { func vbutilIt() error { // Try to read a GPT header from our output file. If we can, add a root_guid // to config.txt, otherwise, don't bother. - args := []string{"gpt", *dev} - msg, err := exec.Command("sudo", args...).Output() - if err != nil { - log.Printf("gpt %v failed (warning only): %v", args, err) - } + var pt = &gpt.PartitionTable{} var pg gpt.GUID - if err == nil { - var pt = &gpt.PartitionTable{} + if *dev == "/dev/null" { + log.Printf("Skipping the gpt step, since *dev is /dev/null") + } else { + gptcmd, err := exec.LookPath("gpt") + if err != nil { + return fmt.Errorf("Can not find a GPT command: %v", err) + } + args := []string{gptcmd, *dev} + msg, err := exec.Command("sudo", args...).Output() + if err != nil { + return fmt.Errorf("gpt %v failed: %v", args, err) + } + if err := json.NewDecoder(bytes.NewBuffer(msg)).Decode(&pt); err != nil { log.Printf("Reading in GPT JSON, warning only: %v", err) } else if pt.Primary == nil || pt.MasterBootRecord == nil { @@ -436,7 +431,7 @@ func run(name string, args ...string) error { } func tcz() error { - return run("tcz", append([]string{"-d", "-i=false", "-r=tcz"}, tczList...)...) + return run("tcz", append([]string{"-d", "-i=false", "-r=rootfs/tcz"}, tczList...)...) } func check() error {