diff options
37 files changed, 188 insertions, 169 deletions
diff --git a/runsc/boot/events.go b/runsc/boot/events.go index 0814b2a69..65137de8a 100644 --- a/runsc/boot/events.go +++ b/runsc/boot/events.go @@ -91,7 +91,7 @@ func (cm *containerManager) Event(_ *struct{}, out *EventOut) error { // Memory usage. // TODO(gvisor.dev/issue/172): Per-container accounting. mem := cm.l.k.MemoryFile() - mem.UpdateUsage() + _ = mem.UpdateUsage() // best effort to update. _, totalUsage := usage.MemoryAccounting.Copy() out.Event.Data.Memory.Usage = MemoryEntry{ Usage: totalUsage, diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index 7fce2b708..40cf2a3df 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -69,7 +69,7 @@ const ( // tmpfs has some extra supported options that we must pass through. var tmpfsAllowedData = []string{"mode", "uid", "gid"} -func addOverlay(ctx context.Context, conf *config.Config, lower *fs.Inode, name string, lowerFlags fs.MountSourceFlags) (*fs.Inode, error) { +func addOverlay(ctx context.Context, lower *fs.Inode, name string, lowerFlags fs.MountSourceFlags) (*fs.Inode, error) { // Upper layer uses the same flags as lower, but it must be read-write. upperFlags := lowerFlags upperFlags.ReadOnly = false @@ -744,7 +744,7 @@ func (c *containerMounter) mountSharedMaster(ctx context.Context, conf *config.C if useOverlay { log.Debugf("Adding overlay on top of shared mount %q", hint.name) - inode, err = addOverlay(ctx, conf, inode, hint.mount.Type, mf) + inode, err = addOverlay(ctx, inode, hint.mount.Type, mf) if err != nil { return nil, err } @@ -785,7 +785,7 @@ func (c *containerMounter) createRootMount(ctx context.Context, conf *config.Con if conf.Overlay && !c.root.Readonly { log.Debugf("Adding overlay on top of root mount") // Overlay a tmpfs filesystem on top of the root. - rootInode, err = addOverlay(ctx, conf, rootInode, "root-overlay-upper", mf) + rootInode, err = addOverlay(ctx, rootInode, "root-overlay-upper", mf) if err != nil { return nil, err } @@ -901,7 +901,7 @@ func (c *containerMounter) mountSubmount(ctx context.Context, conf *config.Confi if useOverlay { log.Debugf("Adding overlay on top of mount %q", m.Destination) - inode, err = addOverlay(ctx, conf, inode, m.Type, mf) + inode, err = addOverlay(ctx, inode, m.Type, mf) if err != nil { return err } diff --git a/runsc/cgroup/cgroup.go b/runsc/cgroup/cgroup.go index 66a6a0f68..5dbf14376 100644 --- a/runsc/cgroup/cgroup.go +++ b/runsc/cgroup/cgroup.go @@ -424,10 +424,9 @@ func (c *Cgroup) Uninstall() error { // restores cgroup to the original state. func (c *Cgroup) Join() (func(), error) { // First save the current state so it can be restored. - undo := func() {} paths, err := loadPaths("self") if err != nil { - return undo, err + return nil, err } var undoPaths []string for ctrlr, path := range paths { @@ -438,8 +437,7 @@ func (c *Cgroup) Join() (func(), error) { } } - // Replace empty undo with the real thing before changes are made to cgroups. - undo = func() { + cu := cleanup.Make(func() { for _, path := range undoPaths { log.Debugf("Restoring cgroup %q", path) // Writing the value 0 to a cgroup.procs file causes @@ -449,7 +447,8 @@ func (c *Cgroup) Join() (func(), error) { log.Warningf("Error restoring cgroup %q: %v", path, err) } } - } + }) + defer cu.Clean() // Now join the cgroups. for key, ctrlr := range controllers { @@ -461,10 +460,10 @@ func (c *Cgroup) Join() (func(), error) { if ctrlr.optional() && os.IsNotExist(err) { continue } - return undo, err + return nil, err } } - return undo, nil + return cu.Release(), nil } // CPUQuota returns the CFS CPU quota. diff --git a/runsc/cgroup/cgroup_test.go b/runsc/cgroup/cgroup_test.go index eba40621e..1431b4e8f 100644 --- a/runsc/cgroup/cgroup_test.go +++ b/runsc/cgroup/cgroup_test.go @@ -800,7 +800,7 @@ func TestLoadPaths(t *testing.T) { if err != nil { t.Fatalf("Unexpected error: %v", err) } - } else if !strings.Contains(err.Error(), tc.err) { + } else if err == nil || !strings.Contains(err.Error(), tc.err) { t.Fatalf("Wrong error message, want: *%s*, got: %v", tc.err, err) } for key, vWant := range tc.want { diff --git a/runsc/cli/main.go b/runsc/cli/main.go index 76184cd9c..3556d7665 100644 --- a/runsc/cli/main.go +++ b/runsc/cli/main.go @@ -243,7 +243,7 @@ func Main(version string) { subcmdCode := subcommands.Execute(context.Background(), conf, &ws) // Check for leaks and write coverage report before os.Exit(). refsvfs2.DoLeakCheck() - coverage.Report() + _ = coverage.Report() if subcmdCode == subcommands.ExitSuccess { log.Infof("Exiting with status: %v", ws) if ws.Signaled() { diff --git a/runsc/cmd/capability_test.go b/runsc/cmd/capability_test.go index e13a94486..99075d82d 100644 --- a/runsc/cmd/capability_test.go +++ b/runsc/cmd/capability_test.go @@ -122,6 +122,9 @@ func TestCapabilities(t *testing.T) { func TestMain(m *testing.M) { flag.Parse() - specutils.MaybeRunAsRoot() + if err := specutils.MaybeRunAsRoot(); err != nil { + fmt.Fprintf(os.Stderr, "Error running as root: %v", err) + os.Exit(123) + } os.Exit(m.Run()) } diff --git a/runsc/cmd/do.go b/runsc/cmd/do.go index 5485db149..6cf76f644 100644 --- a/runsc/cmd/do.go +++ b/runsc/cmd/do.go @@ -225,25 +225,25 @@ func (c *Do) setupNet(cid string, spec *specs.Spec) (func(), error) { args := strings.Split(cmd, " ") cmd := exec.Command(args[0], args[1:]...) if err := cmd.Run(); err != nil { - c.cleanupNet(cid, dev, "", "", "") + c.cleanupNet(cid, "", "", "") return nil, fmt.Errorf("failed to run %q: %v", cmd, err) } } resolvPath, err := makeFile("/etc/resolv.conf", "nameserver 8.8.8.8\n", spec) if err != nil { - c.cleanupNet(cid, dev, "", "", "") + c.cleanupNet(cid, "", "", "") return nil, err } hostnamePath, err := makeFile("/etc/hostname", cid+"\n", spec) if err != nil { - c.cleanupNet(cid, dev, resolvPath, "", "") + c.cleanupNet(cid, resolvPath, "", "") return nil, err } hosts := fmt.Sprintf("127.0.0.1\tlocalhost\n%s\t%s\n", c.ip, cid) hostsPath, err := makeFile("/etc/hosts", hosts, spec) if err != nil { - c.cleanupNet(cid, dev, resolvPath, hostnamePath, "") + c.cleanupNet(cid, resolvPath, hostnamePath, "") return nil, err } @@ -253,7 +253,7 @@ func (c *Do) setupNet(cid string, spec *specs.Spec) (func(), error) { } addNamespace(spec, netns) - return func() { c.cleanupNet(cid, dev, resolvPath, hostnamePath, hostsPath) }, nil + return func() { c.cleanupNet(cid, resolvPath, hostnamePath, hostsPath) }, nil } // cleanupNet tries to cleanup the network setup in setupNet. @@ -263,7 +263,7 @@ func (c *Do) setupNet(cid string, spec *specs.Spec) (func(), error) { // // Unfortunately none of this can be automatically cleaned up on process exit, // we must do so explicitly. -func (c *Do) cleanupNet(cid, dev, resolvPath, hostnamePath, hostsPath string) { +func (c *Do) cleanupNet(cid, resolvPath, hostnamePath, hostsPath string) { _, peer := deviceNames(cid) cmds := []string{ diff --git a/runsc/cmd/error.go b/runsc/cmd/error.go index 3585b5448..96c5c1e8d 100644 --- a/runsc/cmd/error.go +++ b/runsc/cmd/error.go @@ -58,7 +58,7 @@ func Errorf(format string, args ...interface{}) subcommands.ExitStatus { panic(err) } if ErrorLogger != nil { - ErrorLogger.Write(b) + _, _ = ErrorLogger.Write(b) } return subcommands.ExitFailure diff --git a/runsc/cmd/events.go b/runsc/cmd/events.go index 06f00e8e7..c1d029d7f 100644 --- a/runsc/cmd/events.go +++ b/runsc/cmd/events.go @@ -97,7 +97,9 @@ func (evs *Events) Execute(ctx context.Context, f *flag.FlagSet, args ...interfa if err != nil { log.Warningf("Error while marshalling event %v: %v", ev.Event, err) } else { - os.Stdout.Write(b) + if _, err := os.Stdout.Write(b); err != nil { + Fatalf("Error writing to stdout: %v", err) + } } // If we're only running once, break. If we're only running diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index f5eabce74..20e05f141 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -284,8 +284,12 @@ func setupRootFS(spec *specs.Spec, conf *config.Config) error { } // Prepare tree structure for pivot_root(2). - os.Mkdir("/proc/proc", 0755) - os.Mkdir("/proc/root", 0755) + if err := os.Mkdir("/proc/proc", 0755); err != nil { + Fatalf("%v", err) + } + if err := os.Mkdir("/proc/root", 0755); err != nil { + Fatalf("%v", err) + } // This cannot use SafeMount because there's no available procfs. But we // know that /proc is an empty tmpfs mount, so this is safe. if err := unix.Mount("runsc-proc", "/proc/proc", "proc", flags|unix.MS_RDONLY, ""); err != nil { @@ -405,7 +409,7 @@ func resolveMounts(conf *config.Config, mounts []specs.Mount, root string) ([]sp panic(fmt.Sprintf("%q could not be made relative to %q: %v", dst, root, err)) } - opts, err := adjustMountOptions(conf, filepath.Join(root, relDst), m.Options) + opts, err := adjustMountOptions(filepath.Join(root, relDst), m.Options) if err != nil { return nil, err } @@ -471,7 +475,7 @@ func resolveSymlinksImpl(root, base, rel string, followCount uint) (string, erro } // adjustMountOptions adds 'overlayfs_stale_read' if mounting over overlayfs. -func adjustMountOptions(conf *config.Config, path string, opts []string) ([]string, error) { +func adjustMountOptions(path string, opts []string) ([]string, error) { rv := make([]string, len(opts)) copy(rv, opts) diff --git a/runsc/cmd/help.go b/runsc/cmd/help.go index cd85dabbb..35545e938 100644 --- a/runsc/cmd/help.go +++ b/runsc/cmd/help.go @@ -58,7 +58,7 @@ func (*Help) Usage() string { } // SetFlags implements subcommands.Command.SetFlags. -func (h *Help) SetFlags(f *flag.FlagSet) {} +func (h *Help) SetFlags(*flag.FlagSet) {} // Execute implements subcommands.Command.Execute. func (h *Help) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { diff --git a/runsc/cmd/install.go b/runsc/cmd/install.go index 2e223e3be..dc9e01d95 100644 --- a/runsc/cmd/install.go +++ b/runsc/cmd/install.go @@ -58,7 +58,7 @@ func (i *Install) SetFlags(fs *flag.FlagSet) { } // Execute implements subcommands.Command.Execute. -func (i *Install) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { +func (i *Install) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus { // Grab the name and arguments. runtimeArgs := f.Args() @@ -134,7 +134,7 @@ func (u *Uninstall) SetFlags(fs *flag.FlagSet) { } // Execute implements subcommands.Command.Execute. -func (u *Uninstall) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { +func (u *Uninstall) Execute(context.Context, *flag.FlagSet, ...interface{}) subcommands.ExitStatus { log.Printf("Removing runtime %q from %q.", u.Runtime, u.ConfigFile) c, err := readConfig(u.ConfigFile) diff --git a/runsc/cmd/list.go b/runsc/cmd/list.go index 9f9a47bd8..2adfcced7 100644 --- a/runsc/cmd/list.go +++ b/runsc/cmd/list.go @@ -102,7 +102,7 @@ func (l *List) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) c.CreatedAt.Format(time.RFC3339Nano), c.Owner) } - w.Flush() + _ = w.Flush() case "json": // Print just the states. var states []specs.State diff --git a/runsc/cmd/mitigate_test.go b/runsc/cmd/mitigate_test.go index 2d3fef7c1..59ec70d08 100644 --- a/runsc/cmd/mitigate_test.go +++ b/runsc/cmd/mitigate_test.go @@ -153,11 +153,7 @@ func (m *Mitigate) doExecuteTest(t *testing.T, name, data string, want int, want func checkErr(want, got error) error { switch { case want == nil && got == nil: - case want != nil && got == nil: - fallthrough - case want == nil && got != nil: - fallthrough - case want.Error() != strings.Trim(got.Error(), " "): + case want == nil || got == nil || want.Error() != strings.Trim(got.Error(), " "): return fmt.Errorf("got: %v want: %v", got, want) } return nil diff --git a/runsc/cmd/pause.go b/runsc/cmd/pause.go index 15ef7b577..9768f1cfb 100644 --- a/runsc/cmd/pause.go +++ b/runsc/cmd/pause.go @@ -42,7 +42,7 @@ func (*Pause) Usage() string { } // SetFlags implements subcommands.Command.SetFlags. -func (*Pause) SetFlags(f *flag.FlagSet) { +func (*Pause) SetFlags(*flag.FlagSet) { } // Execute implements subcommands.Command.Execute. diff --git a/runsc/cmd/resume.go b/runsc/cmd/resume.go index 856469252..d62e89e80 100644 --- a/runsc/cmd/resume.go +++ b/runsc/cmd/resume.go @@ -43,7 +43,7 @@ func (*Resume) Usage() string { } // SetFlags implements subcommands.Command.SetFlags. -func (r *Resume) SetFlags(f *flag.FlagSet) { +func (r *Resume) SetFlags(*flag.FlagSet) { } // Execute implements subcommands.Command.Execute. diff --git a/runsc/cmd/start.go b/runsc/cmd/start.go index 964a65064..7c395d722 100644 --- a/runsc/cmd/start.go +++ b/runsc/cmd/start.go @@ -43,7 +43,7 @@ func (*Start) Usage() string { } // SetFlags implements subcommands.Command.SetFlags. -func (*Start) SetFlags(f *flag.FlagSet) {} +func (*Start) SetFlags(*flag.FlagSet) {} // Execute implements subcommands.Command.Execute. func (*Start) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { diff --git a/runsc/cmd/state.go b/runsc/cmd/state.go index 1f7913d5a..061003bab 100644 --- a/runsc/cmd/state.go +++ b/runsc/cmd/state.go @@ -45,7 +45,7 @@ func (*State) Usage() string { } // SetFlags implements subcommands.Command.SetFlags. -func (*State) SetFlags(f *flag.FlagSet) {} +func (*State) SetFlags(*flag.FlagSet) {} // Execute implements subcommands.Command.Execute. func (*State) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { @@ -71,6 +71,8 @@ func (*State) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s if err != nil { Fatalf("marshaling container state: %v", err) } - os.Stdout.Write(b) + if _, err := os.Stdout.Write(b); err != nil { + Fatalf("Error writing to stdout: %v", err) + } return subcommands.ExitSuccess } diff --git a/runsc/cmd/syscalls.go b/runsc/cmd/syscalls.go index a8c83d662..608be9bb4 100644 --- a/runsc/cmd/syscalls.go +++ b/runsc/cmd/syscalls.go @@ -103,7 +103,7 @@ func (s *Syscalls) SetFlags(f *flag.FlagSet) { } // Execute implements subcommands.Command.Execute. -func (s *Syscalls) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { +func (s *Syscalls) Execute(context.Context, *flag.FlagSet, ...interface{}) subcommands.ExitStatus { out, ok := outputMap[s.format] if !ok { Fatalf("Unsupported output format %q", s.format) diff --git a/runsc/cmd/verity_prepare.go b/runsc/cmd/verity_prepare.go index 66128b2a3..85d762a51 100644 --- a/runsc/cmd/verity_prepare.go +++ b/runsc/cmd/verity_prepare.go @@ -88,7 +88,7 @@ func (c *VerityPrepare) Execute(_ context.Context, f *flag.FlagSet, args ...inte }, Hostname: hostname, Mounts: []specs.Mount{ - specs.Mount{ + { Source: c.dir, Destination: "/verityroot", Type: "bind", diff --git a/runsc/config/config_test.go b/runsc/config/config_test.go index fb162b7eb..80ff2c0a6 100644 --- a/runsc/config/config_test.go +++ b/runsc/config/config_test.go @@ -41,21 +41,37 @@ func TestDefault(t *testing.T) { } } -func setDefault(name string) { +func setDefault(name string) error { fl := flag.CommandLine.Lookup(name) - fl.Value.Set(fl.DefValue) + return fl.Value.Set(fl.DefValue) } func TestFromFlags(t *testing.T) { - flag.CommandLine.Lookup("root").Value.Set("some-path") - flag.CommandLine.Lookup("debug").Value.Set("true") - flag.CommandLine.Lookup("num-network-channels").Value.Set("123") - flag.CommandLine.Lookup("network").Value.Set("none") + if err := flag.CommandLine.Lookup("root").Value.Set("some-path"); err != nil { + t.Errorf("Flag set: %v", err) + } + if err := flag.CommandLine.Lookup("debug").Value.Set("true"); err != nil { + t.Errorf("Flag set: %v", err) + } + if err := flag.CommandLine.Lookup("num-network-channels").Value.Set("123"); err != nil { + t.Errorf("Flag set: %v", err) + } + if err := flag.CommandLine.Lookup("network").Value.Set("none"); err != nil { + t.Errorf("Flag set: %v", err) + } defer func() { - setDefault("root") - setDefault("debug") - setDefault("num-network-channels") - setDefault("network") + if err := setDefault("root"); err != nil { + t.Errorf("Flag set: %v", err) + } + if err := setDefault("debug"); err != nil { + t.Errorf("Flag set: %v", err) + } + if err := setDefault("num-network-channels"); err != nil { + t.Errorf("Flag set: %v", err) + } + if err := setDefault("network"); err != nil { + t.Errorf("Flag set: %v", err) + } }() c, err := NewFromFlags() diff --git a/runsc/container/console_test.go b/runsc/container/console_test.go index 79b056fce..8c65b9cd4 100644 --- a/runsc/container/console_test.go +++ b/runsc/container/console_test.go @@ -308,7 +308,9 @@ func TestJobControlSignalExec(t *testing.T) { } // Execute sleep. - ptyMaster.Write([]byte("sleep 100\n")) + if _, err := ptyMaster.Write([]byte("sleep 100\n")); err != nil { + t.Fatalf("ptyMaster.Write: %v", err) + } // Wait for it to start. Sleep's PPID is bash's PID. expectedPL = append(expectedPL, newProcessBuilder().PID(3).PPID(2).Cmd("sleep").Process()) @@ -411,7 +413,9 @@ func TestJobControlSignalRootContainer(t *testing.T) { // which makes this a suitable Reader for WaitUntilRead. ptyBuf := newBlockingBuffer() tee := io.TeeReader(ptyMaster, ptyBuf) - go io.Copy(os.Stderr, tee) + go func() { + _, _ = io.Copy(os.Stderr, tee) + }() // Start the container. if err := c.Start(conf); err != nil { @@ -444,7 +448,9 @@ func TestJobControlSignalRootContainer(t *testing.T) { } // Execute sleep via the terminal. - ptyMaster.Write([]byte("sleep 100\n")) + if _, err := ptyMaster.Write([]byte("sleep 100\n")); err != nil { + t.Fatalf("ptyMaster.Write(): %v", err) + } // Wait for sleep to start. expectedPL = append(expectedPL, newProcessBuilder().PID(2).PPID(1).Cmd("sleep").Process()) @@ -563,13 +569,15 @@ func TestMultiContainerTerminal(t *testing.T) { // file. Writes after a certain point will block unless we drain the // PTY, so we must continually copy from it. // - // We log the output to stderr for debugabilitly, and also to a buffer, + // We log the output to stderr for debuggability, and also to a buffer, // since we wait on particular output from bash below. We use a custom // blockingBuffer which is thread-safe and also blocks on Read calls, // which makes this a suitable Reader for WaitUntilRead. ptyBuf := newBlockingBuffer() tee := io.TeeReader(tc.master, ptyBuf) - go io.Copy(os.Stderr, tee) + go func() { + _, _ = io.Copy(os.Stderr, tee) + }() // Wait for bash to start. expectedPL := []*control.Process{ @@ -581,7 +589,9 @@ func TestMultiContainerTerminal(t *testing.T) { // Execute echo command and check that it was executed correctly. Use // a variable to ensure it's not matching against command echo. - tc.master.Write([]byte("echo foo-${PWD}-123\n")) + if _, err := tc.master.Write([]byte("echo foo-${PWD}-123\n")); err != nil { + t.Fatalf("master.Write(): %v", err) + } if err := testutil.WaitUntilRead(ptyBuf, "foo-/-123", 5*time.Second); err != nil { t.Fatalf("echo didn't execute: %v", err) } diff --git a/runsc/container/container.go b/runsc/container/container.go index 0820edaec..b789bc7da 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -208,7 +208,7 @@ func New(conf *config.Config, args Args) (*Container, error) { if err := c.Saver.lockForNew(); err != nil { return nil, err } - defer c.Saver.unlock() + defer c.Saver.unlockOrDie() // If the metadata annotations indicate that this container should be started // in an existing sandbox, we must do so. These are the possible metadata @@ -340,7 +340,7 @@ func (c *Container) Start(conf *config.Config) error { if err := c.Saver.lock(); err != nil { return err } - unlock := cleanup.Make(func() { c.Saver.unlock() }) + unlock := cleanup.Make(c.Saver.unlockOrDie) defer unlock.Clean() if err := c.requireStatus("start", Created); err != nil { @@ -426,7 +426,7 @@ func (c *Container) Restore(spec *specs.Spec, conf *config.Config, restoreFile s if err := c.Saver.lock(); err != nil { return err } - defer c.Saver.unlock() + defer c.Saver.unlockOrDie() if err := c.requireStatus("restore", Created); err != nil { return err @@ -614,7 +614,7 @@ func (c *Container) Pause() error { if err := c.Saver.lock(); err != nil { return err } - defer c.Saver.unlock() + defer c.Saver.unlockOrDie() if c.Status != Created && c.Status != Running { return fmt.Errorf("cannot pause container %q in state %v", c.ID, c.Status) @@ -634,7 +634,7 @@ func (c *Container) Resume() error { if err := c.Saver.lock(); err != nil { return err } - defer c.Saver.unlock() + defer c.Saver.unlockOrDie() if c.Status != Paused { return fmt.Errorf("cannot resume container %q in state %v", c.ID, c.Status) @@ -675,8 +675,8 @@ func (c *Container) Destroy() error { return err } defer func() { - c.Saver.unlock() - c.Saver.close() + c.Saver.unlockOrDie() + _ = c.Saver.close() }() // Stored for later use as stop() sets c.Sandbox to nil. @@ -1020,10 +1020,10 @@ func runInCgroup(cg *cgroup.Cgroup, fn func() error) error { return fn() } restore, err := cg.Join() - defer restore() if err != nil { return err } + defer restore() return fn() } diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index 249324c5a..7360eae35 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -53,7 +53,10 @@ func TestMain(m *testing.M) { if err := testutil.ConfigureExePath(); err != nil { panic(err.Error()) } - specutils.MaybeRunAsRoot() + if err := specutils.MaybeRunAsRoot(); err != nil { + fmt.Fprintf(os.Stderr, "Error running as root: %v", err) + os.Exit(123) + } os.Exit(m.Run()) } @@ -523,9 +526,11 @@ func TestLifecycle(t *testing.T) { ws, err := c.Wait() if err != nil { ch <- err + return } if got, want := ws.Signal(), unix.SIGTERM; got != want { ch <- fmt.Errorf("got signal %v, want %v", got, want) + return } ch <- nil }() @@ -1525,7 +1530,9 @@ func TestCapabilities(t *testing.T) { defer os.Remove(exePath) // Need to traverse the intermediate directory. - os.Chmod(rootDir, 0755) + if err := os.Chmod(rootDir, 0755); err != nil { + t.Fatal(err) + } execArgs := &control.ExecArgs{ Filename: exePath, @@ -2153,7 +2160,7 @@ func doDestroyStartingTest(t *testing.T, vfs2 bool) { go func() { defer wg.Done() // Ignore failures, start can fail if destroy runs first. - startCont.Start(conf) + _ = startCont.Start(conf) }() wg.Add(1) diff --git a/runsc/container/hook.go b/runsc/container/hook.go index 901607aee..ce1c9e1de 100644 --- a/runsc/container/hook.go +++ b/runsc/container/hook.go @@ -101,8 +101,8 @@ func executeHook(h specs.Hook, s specs.State) error { return fmt.Errorf("failure executing hook %q, err: %v\nstdout: %s\nstderr: %s", h.Path, err, stdout.String(), stderr.String()) } case <-timer: - cmd.Process.Kill() - cmd.Wait() + _ = cmd.Process.Kill() + _ = cmd.Wait() return fmt.Errorf("timeout executing hook %q\nstdout: %s\nstderr: %s", h.Path, stdout.String(), stderr.String()) } diff --git a/runsc/container/multi_container_test.go b/runsc/container/multi_container_test.go index 0dbe1e323..58ae18232 100644 --- a/runsc/container/multi_container_test.go +++ b/runsc/container/multi_container_test.go @@ -894,7 +894,9 @@ func TestMultiContainerKillAll(t *testing.T) { if tc.killContainer { // First kill the init process to make the container be stopped with // processes still running inside. - containers[1].SignalContainer(unix.SIGKILL, false) + if err := containers[1].SignalContainer(unix.SIGKILL, false); err != nil { + t.Fatalf("SignalContainer(): %v", err) + } op := func() error { c, err := Load(conf.RootDir, FullID{ContainerID: ids[1]}, LoadOpts{}) if err != nil { @@ -912,7 +914,7 @@ func TestMultiContainerKillAll(t *testing.T) { c, err := Load(conf.RootDir, FullID{ContainerID: ids[1]}, LoadOpts{}) if err != nil { - t.Fatalf("failed to load child container %q: %v", c.ID, err) + t.Fatalf("failed to load child container %q: %v", ids[1], err) } // Kill'Em All if err := c.SignalContainer(unix.SIGKILL, true); err != nil { @@ -1040,7 +1042,8 @@ func TestMultiContainerDestroyStarting(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - startCont.Start(conf) // ignore failures, start can fail if destroy runs first. + // Ignore failures, start can fail if destroy runs first. + _ = startCont.Start(conf) }() wg.Add(1) @@ -1980,7 +1983,7 @@ func TestMultiContainerEvent(t *testing.T) { if busyUsage <= sleepUsage { t.Logf("Busy container usage lower than sleep (busy: %d, sleep: %d), retrying...", busyUsage, sleepUsage) - return fmt.Errorf("Busy container should have higher usage than sleep, busy: %d, sleep: %d", busyUsage, sleepUsage) + return fmt.Errorf("busy container should have higher usage than sleep, busy: %d, sleep: %d", busyUsage, sleepUsage) } return nil } diff --git a/runsc/container/shared_volume_test.go b/runsc/container/shared_volume_test.go index cb5bffb89..7d05ee16b 100644 --- a/runsc/container/shared_volume_test.go +++ b/runsc/container/shared_volume_test.go @@ -173,7 +173,7 @@ func checkFile(c *Container, filename string, want []byte) error { } got, err := ioutil.ReadFile(cpy) if err != nil { - return fmt.Errorf("Error reading file %q: %v", filename, err) + return fmt.Errorf("error reading file %q: %v", filename, err) } if !bytes.Equal(got, want) { return fmt.Errorf("file content inside the sandbox is wrong, got: %q, want: %q", got, want) diff --git a/runsc/container/state_file.go b/runsc/container/state_file.go index 0399903a0..23810f593 100644 --- a/runsc/container/state_file.go +++ b/runsc/container/state_file.go @@ -264,10 +264,10 @@ func (s *StateFile) lockForNew() error { // Checks if the container already exists by looking for the metadata file. if _, err := os.Stat(s.statePath()); err == nil { - s.unlock() + s.unlockOrDie() return fmt.Errorf("container already exists") } else if !os.IsNotExist(err) { - s.unlock() + s.unlockOrDie() return fmt.Errorf("looking for existing container: %v", err) } return nil @@ -286,6 +286,15 @@ func (s *StateFile) unlock() error { return nil } +func (s *StateFile) unlockOrDie() { + if !s.flock.Locked() { + panic("unlock called without lock held") + } + if err := s.flock.Unlock(); err != nil { + panic(fmt.Sprintf("Error releasing lock on %q: %v", s.flock, err)) + } +} + // saveLocked saves 'v' to the state file. // // Preconditions: lock() must been called before. @@ -308,7 +317,7 @@ func (s *StateFile) load(v interface{}) error { if err := s.lock(); err != nil { return err } - defer s.unlock() + defer s.unlockOrDie() metaBytes, err := ioutil.ReadFile(s.statePath()) if err != nil { diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go index 3f362b25e..07497e47b 100644 --- a/runsc/fsgofer/fsgofer.go +++ b/runsc/fsgofer/fsgofer.go @@ -51,10 +51,10 @@ const ( // verityXattrs are the extended attributes used by verity file system. var verityXattrs = map[string]struct{}{ - "user.merkle.offset": struct{}{}, - "user.merkle.size": struct{}{}, - "user.merkle.childrenOffset": struct{}{}, - "user.merkle.childrenSize": struct{}{}, + "user.merkle.offset": {}, + "user.merkle.size": {}, + "user.merkle.childrenOffset": {}, + "user.merkle.childrenSize": {}, } // join is equivalent to path.Join() but skips path.Clean() which is expensive. diff --git a/runsc/fsgofer/fsgofer_test.go b/runsc/fsgofer/fsgofer_test.go index 77723827a..ee6cc97df 100644 --- a/runsc/fsgofer/fsgofer_test.go +++ b/runsc/fsgofer/fsgofer_test.go @@ -65,15 +65,6 @@ func configTestName(conf *Config) string { return "RWMount" } -func assertPanic(t *testing.T, f func()) { - defer func() { - if r := recover(); r == nil { - t.Errorf("function did not panic") - } - }() - f() -} - func testReadWrite(f p9.File, flags p9.OpenFlags, content []byte) error { want := make([]byte, len(content)) copy(want, content) @@ -195,7 +186,7 @@ func setup(fileType uint32) (string, string, error) { } root, err := a.Attach() if err != nil { - return "", "", fmt.Errorf("Attach failed, err: %v", err) + return "", "", fmt.Errorf("attach failed, err: %v", err) } defer root.Close() @@ -290,10 +281,10 @@ func checkIDs(f p9.File, uid, gid int) error { return fmt.Errorf("GetAttr() failed, err: %v", err) } if want := p9.UID(uid); stat.UID != want { - return fmt.Errorf("Wrong UID, want: %v, got: %v", want, stat.UID) + return fmt.Errorf("wrong UID, want: %v, got: %v", want, stat.UID) } if want := p9.GID(gid); stat.GID != want { - return fmt.Errorf("Wrong GID, want: %v, got: %v", want, stat.GID) + return fmt.Errorf("wrong GID, want: %v, got: %v", want, stat.GID) } return nil } @@ -574,7 +565,7 @@ func SetGetXattr(l *localFile, name string, value string) error { return err } if ret != value { - return fmt.Errorf("Got value %s, want %s", ret, value) + return fmt.Errorf("got value %s, want %s", ret, value) } return nil } diff --git a/runsc/mitigate/mitigate.go b/runsc/mitigate/mitigate.go index 88409af8f..9f29ec873 100644 --- a/runsc/mitigate/mitigate.go +++ b/runsc/mitigate/mitigate.go @@ -159,7 +159,7 @@ func (c ThreadGroup) String() string { func getThreads(data string) ([]Thread, error) { // Each processor entry should start with the // processor key. Find the beginings of each. - r := buildRegex(processorKey, `\d+`) + r := buildRegex(processorKey) indices := r.FindAllStringIndex(data, -1) if len(indices) < 1 { return nil, fmt.Errorf("no cpus found for: %q", data) @@ -437,14 +437,14 @@ func parseIntegerResult(data, key string) (int64, error) { } // buildRegex builds a regex for parsing each CPU field. -func buildRegex(key, match string) *regexp.Regexp { +func buildRegex(key string) *regexp.Regexp { reg := fmt.Sprintf(`(?m)^%s\s*:\s*(.*)$`, key) return regexp.MustCompile(reg) } // parseRegex parses data with key inserted into a standard regex template. func parseRegex(data, key, match string) (string, error) { - r := buildRegex(key, match) + r := buildRegex(key) matches := r.FindStringSubmatch(data) if len(matches) < 2 { diff --git a/runsc/mitigate/mitigate_test.go b/runsc/mitigate/mitigate_test.go index 890c65f05..1a3b880ca 100644 --- a/runsc/mitigate/mitigate_test.go +++ b/runsc/mitigate/mitigate_test.go @@ -126,15 +126,15 @@ bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa coreID: 0, }, bugs: map[string]struct{}{ - "cpu_meltdown": struct{}{}, - "spectre_v1": struct{}{}, - "spectre_v2": struct{}{}, - "spec_store_bypass": struct{}{}, - "l1tf": struct{}{}, - "mds": struct{}{}, - "swapgs": struct{}{}, - "taa": struct{}{}, - "itlb_multihit": struct{}{}, + "cpu_meltdown": {}, + "spectre_v1": {}, + "spectre_v2": {}, + "spec_store_bypass": {}, + "l1tf": {}, + "mds": {}, + "swapgs": {}, + "taa": {}, + "itlb_multihit": {}, }, } @@ -235,13 +235,13 @@ power management: cpuFamily: 6, model: 63, bugs: map[string]struct{}{ - "cpu_meltdown": struct{}{}, - "spectre_v1": struct{}{}, - "spectre_v2": struct{}{}, - "spec_store_bypass": struct{}{}, - "l1tf": struct{}{}, - "mds": struct{}{}, - "swapgs": struct{}{}, + "cpu_meltdown": {}, + "spectre_v1": {}, + "spectre_v2": {}, + "spec_store_bypass": {}, + "l1tf": {}, + "mds": {}, + "swapgs": {}, }, } @@ -334,38 +334,6 @@ cache_alignment : 64 address sizes : 46 bits physical, 48 bits virtual power management:` - const cascade = `processor : 0 -vendor_id : GenuineIntel -cpu family : 6 -model : 85 -model name : Intel(R) Xeon(R) CPU -stepping : 7 -microcode : 0x1 -cpu MHz : 2800.198 -cache size : 33792 KB -physical id : 0 -siblings : 2 -core id : 0 -cpu cores : 1 -apicid : 0 -initial apicid : 0 -fpu : yes -fpu_exception : yes -cpuid level : 13 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 - ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmu -lqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowpr -efetch invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid r -tm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves a -rat avx512_vnni md_clear arch_capabilities -bugs : spectre_v1 spectre_v2 spec_store_bypass mds swapgs taa -bogomips : 5600.39 -clflush size : 64 -cache_alignment : 64 -address sizes : 46 bits physical, 48 bits virtual -power management:` - const amd = `processor : 0 vendor_id : AuthenticAMD cpu family : 23 @@ -429,7 +397,7 @@ power management:` }() if got != tc.vulnerable { - t.Fatalf("Mismatch vulnerable for cpu %+s: got %t want: %t", tc.name, tc.vulnerable, got) + t.Fatalf("Mismatch vulnerable for cpu %s: got %t want: %t", tc.name, tc.vulnerable, got) } } }) diff --git a/runsc/sandbox/network.go b/runsc/sandbox/network.go index f69558021..3451d1037 100644 --- a/runsc/sandbox/network.go +++ b/runsc/sandbox/network.go @@ -49,7 +49,7 @@ import ( // // Run the following container to test it: // docker run -di --runtime=runsc -p 8080:80 -v $PWD:/usr/local/apache2/htdocs/ httpd:2.4 -func setupNetwork(conn *urpc.Client, pid int, spec *specs.Spec, conf *config.Config) error { +func setupNetwork(conn *urpc.Client, pid int, conf *config.Config) error { log.Infof("Setting up network") switch conf.Network { @@ -301,13 +301,13 @@ func createSocket(iface net.Interface, ifaceLink netlink.Link, enableGSO bool) ( // Use SO_RCVBUFFORCE/SO_SNDBUFFORCE because on linux the receive/send buffer // for an AF_PACKET socket is capped by "net.core.rmem_max/wmem_max". - // wmem_max/rmem_max default to a unusually low value of 208KB. This is too low - // for gVisor to be able to receive packets at high throughputs without + // wmem_max/rmem_max default to a unusually low value of 208KB. This is too + // low for gVisor to be able to receive packets at high throughputs without // incurring packet drops. const bufSize = 4 << 20 // 4MB. if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUFFORCE, bufSize); err != nil { - unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUF, bufSize) + _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUF, bufSize) sz, _ := unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUF) if sz < bufSize { @@ -316,10 +316,10 @@ func createSocket(iface net.Interface, ifaceLink netlink.Link, enableGSO bool) ( } if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_SNDBUFFORCE, bufSize); err != nil { - unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_SNDBUF, bufSize) + _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_SNDBUF, bufSize) sz, _ := unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_SNDBUF) if sz < bufSize { - log.Warningf("Failed to increase snd buffer to %d on SOCK_RAW on %s. Curent buffer %d: %v", bufSize, iface.Name, sz, err) + log.Warningf("Failed to increase snd buffer to %d on SOCK_RAW on %s. Current buffer %d: %v", bufSize, iface.Name, sz, err) } } diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index f14cc7229..9dea7c4d2 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -209,7 +209,7 @@ func (s *Sandbox) StartRoot(spec *specs.Spec, conf *config.Config) error { defer conn.Close() // Configure the network. - if err := setupNetwork(conn, s.Pid, spec, conf); err != nil { + if err := setupNetwork(conn, s.Pid, conf); err != nil { return fmt.Errorf("setting up network: %v", err) } @@ -282,7 +282,7 @@ func (s *Sandbox) Restore(cid string, spec *specs.Spec, conf *config.Config, fil defer conn.Close() // Configure the network. - if err := setupNetwork(conn, s.Pid, spec, conf); err != nil { + if err := setupNetwork(conn, s.Pid, conf); err != nil { return fmt.Errorf("setting up network: %v", err) } diff --git a/runsc/specutils/fs.go b/runsc/specutils/fs.go index 9ecd0fde6..ac20696ee 100644 --- a/runsc/specutils/fs.go +++ b/runsc/specutils/fs.go @@ -67,8 +67,8 @@ var optionsMap = map[string]mapping{ // verityMountOptions is the set of valid verity mount option keys. var verityMountOptions = map[string]struct{}{ - "verity.roothash": struct{}{}, - "verity.action": struct{}{}, + "verity.roothash": {}, + "verity.action": {}, } // propOptionsMap is similar to optionsMap, but it lists propagation options diff --git a/runsc/specutils/namespace.go b/runsc/specutils/namespace.go index 69d7ba5c4..21559f5e5 100644 --- a/runsc/specutils/namespace.go +++ b/runsc/specutils/namespace.go @@ -270,7 +270,10 @@ func MaybeRunAsRoot() error { go func() { for { // Forward all signals to child process. - cmd.Process.Signal(<-ch) + sig := <-ch + if err := cmd.Process.Signal(sig); err != nil { + log.Warningf("Error forwarding signal %v to child (PID %d)", sig, cmd.Process.Pid) + } } }() if err := cmd.Wait(); err != nil { diff --git a/runsc/specutils/specutils_test.go b/runsc/specutils/specutils_test.go index 2c86fffe8..e2d3a75dc 100644 --- a/runsc/specutils/specutils_test.go +++ b/runsc/specutils/specutils_test.go @@ -29,7 +29,7 @@ func TestWaitForReadyHappy(t *testing.T) { if err := cmd.Start(); err != nil { t.Fatalf("cmd.Start() failed, err: %v", err) } - defer cmd.Wait() + defer func() { _ = cmd.Wait() }() var count int err := WaitForReady(cmd.Process.Pid, 5*time.Second, func() (bool, error) { @@ -42,7 +42,9 @@ func TestWaitForReadyHappy(t *testing.T) { if err != nil { t.Errorf("ProcessWaitReady got: %v, expected: nil", err) } - cmd.Process.Kill() + if err := cmd.Process.Kill(); err != nil { + t.Errorf("cmd.ProcessKill(): %v", err) + } } func TestWaitForReadyFail(t *testing.T) { @@ -50,7 +52,7 @@ func TestWaitForReadyFail(t *testing.T) { if err := cmd.Start(); err != nil { t.Fatalf("cmd.Start() failed, err: %v", err) } - defer cmd.Wait() + defer func() { _ = cmd.Wait() }() var count int err := WaitForReady(cmd.Process.Pid, 5*time.Second, func() (bool, error) { @@ -58,12 +60,14 @@ func TestWaitForReadyFail(t *testing.T) { count++ return false, nil } - return false, fmt.Errorf("Fake error") + return false, fmt.Errorf("fake error") }) if err == nil { t.Errorf("ProcessWaitReady got: nil, expected: error") } - cmd.Process.Kill() + if err := cmd.Process.Kill(); err != nil { + t.Errorf("cmd.ProcessKill(): %v", err) + } } func TestWaitForReadyNotRunning(t *testing.T) { @@ -71,7 +75,7 @@ func TestWaitForReadyNotRunning(t *testing.T) { if err := cmd.Start(); err != nil { t.Fatalf("cmd.Start() failed, err: %v", err) } - defer cmd.Wait() + defer func() { _ = cmd.Wait() }() err := WaitForReady(cmd.Process.Pid, 5*time.Second, func() (bool, error) { return false, nil @@ -89,15 +93,17 @@ func TestWaitForReadyTimeout(t *testing.T) { if err := cmd.Start(); err != nil { t.Fatalf("cmd.Start() failed, err: %v", err) } - defer cmd.Wait() + defer func() { _ = cmd.Wait() }() err := WaitForReady(cmd.Process.Pid, 50*time.Millisecond, func() (bool, error) { return false, nil }) - if !strings.Contains(err.Error(), "not running yet") { + if err == nil || !strings.Contains(err.Error(), "not running yet") { t.Errorf("ProcessWaitReady got: %v, expected: not running yet", err) } - cmd.Process.Kill() + if err := cmd.Process.Kill(); err != nil { + t.Errorf("cmd.ProcessKill(): %v", err) + } } func TestSpecInvalid(t *testing.T) { |