diff options
author | Andrei Vagin <avagin@google.com> | 2020-03-06 21:12:32 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-06 21:12:32 -0800 |
commit | bf87da89d3c43555fd57e8f1d7aed21b6da78de4 (patch) | |
tree | 744ba15a2f663d64d56bf1c70bdfe4096f6a1af9 /runsc/cmd | |
parent | 89957c6c87b5ad5c7bac68f93d9472388db57702 (diff) | |
parent | ddfc7239be94fa9711df877a66a9718aabff8b96 (diff) |
Merge branch 'master' into pr_lazy_fpsimd_2
Diffstat (limited to 'runsc/cmd')
-rw-r--r-- | runsc/cmd/BUILD | 4 | ||||
-rw-r--r-- | runsc/cmd/boot.go | 2 | ||||
-rw-r--r-- | runsc/cmd/checkpoint.go | 2 | ||||
-rw-r--r-- | runsc/cmd/create.go | 2 | ||||
-rw-r--r-- | runsc/cmd/debug.go | 66 | ||||
-rw-r--r-- | runsc/cmd/delete.go | 2 | ||||
-rw-r--r-- | runsc/cmd/do.go | 2 | ||||
-rw-r--r-- | runsc/cmd/events.go | 2 | ||||
-rw-r--r-- | runsc/cmd/exec.go | 2 | ||||
-rw-r--r-- | runsc/cmd/gofer.go | 2 | ||||
-rw-r--r-- | runsc/cmd/help.go | 2 | ||||
-rw-r--r-- | runsc/cmd/install.go | 2 | ||||
-rw-r--r-- | runsc/cmd/kill.go | 2 | ||||
-rw-r--r-- | runsc/cmd/list.go | 2 | ||||
-rw-r--r-- | runsc/cmd/pause.go | 2 | ||||
-rw-r--r-- | runsc/cmd/ps.go | 2 | ||||
-rw-r--r-- | runsc/cmd/restore.go | 2 | ||||
-rw-r--r-- | runsc/cmd/resume.go | 2 | ||||
-rw-r--r-- | runsc/cmd/run.go | 2 | ||||
-rw-r--r-- | runsc/cmd/spec.go | 2 | ||||
-rw-r--r-- | runsc/cmd/start.go | 2 | ||||
-rw-r--r-- | runsc/cmd/state.go | 2 | ||||
-rw-r--r-- | runsc/cmd/statefile.go | 143 | ||||
-rw-r--r-- | runsc/cmd/syscalls.go | 2 | ||||
-rw-r--r-- | runsc/cmd/wait.go | 2 |
25 files changed, 223 insertions, 34 deletions
diff --git a/runsc/cmd/BUILD b/runsc/cmd/BUILD index 09aa46434..d0bb4613a 100644 --- a/runsc/cmd/BUILD +++ b/runsc/cmd/BUILD @@ -31,6 +31,7 @@ go_library( "spec.go", "start.go", "state.go", + "statefile.go", "syscalls.go", "wait.go", ], @@ -43,6 +44,8 @@ go_library( "//pkg/sentry/control", "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", + "//pkg/state", + "//pkg/state/statefile", "//pkg/sync", "//pkg/unet", "//pkg/urpc", @@ -50,6 +53,7 @@ go_library( "//runsc/boot/platforms", "//runsc/console", "//runsc/container", + "//runsc/flag", "//runsc/fsgofer", "//runsc/fsgofer/filter", "//runsc/specutils", diff --git a/runsc/cmd/boot.go b/runsc/cmd/boot.go index b40fded5b..0f3da69a0 100644 --- a/runsc/cmd/boot.go +++ b/runsc/cmd/boot.go @@ -21,12 +21,12 @@ import ( "strings" "syscall" - "flag" "github.com/google/subcommands" specs "github.com/opencontainers/runtime-spec/specs-go" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/boot/platforms" + "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/specutils" ) diff --git a/runsc/cmd/checkpoint.go b/runsc/cmd/checkpoint.go index d8b3a8573..8a29e521e 100644 --- a/runsc/cmd/checkpoint.go +++ b/runsc/cmd/checkpoint.go @@ -20,11 +20,11 @@ import ( "path/filepath" "syscall" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/specutils" ) diff --git a/runsc/cmd/create.go b/runsc/cmd/create.go index 1815c93b9..910e97577 100644 --- a/runsc/cmd/create.go +++ b/runsc/cmd/create.go @@ -17,10 +17,10 @@ package cmd import ( "context" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/specutils" ) diff --git a/runsc/cmd/debug.go b/runsc/cmd/debug.go index f37415810..b5de2588b 100644 --- a/runsc/cmd/debug.go +++ b/runsc/cmd/debug.go @@ -22,27 +22,30 @@ import ( "syscall" "time" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/sentry/control" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) // Debug implements subcommands.Command for the "debug" command. type Debug struct { - pid int - stacks bool - signal int - profileHeap string - profileCPU string - trace string - strace string - logLevel string - logPackets string - duration time.Duration - ps bool + pid int + stacks bool + signal int + profileHeap string + profileCPU string + profileGoroutine string + profileBlock string + profileMutex string + trace string + strace string + logLevel string + logPackets string + duration time.Duration + ps bool } // Name implements subcommands.Command. @@ -66,6 +69,9 @@ func (d *Debug) SetFlags(f *flag.FlagSet) { f.BoolVar(&d.stacks, "stacks", false, "if true, dumps all sandbox stacks to the log") f.StringVar(&d.profileHeap, "profile-heap", "", "writes heap profile to the given file.") f.StringVar(&d.profileCPU, "profile-cpu", "", "writes CPU profile to the given file.") + f.StringVar(&d.profileGoroutine, "profile-goroutine", "", "writes goroutine profile to the given file.") + f.StringVar(&d.profileBlock, "profile-block", "", "writes block profile to the given file.") + f.StringVar(&d.profileMutex, "profile-mutex", "", "writes mutex profile to the given file.") f.DurationVar(&d.duration, "duration", time.Second, "amount of time to wait for CPU and trace profiles") f.StringVar(&d.trace, "trace", "", "writes an execution trace to the given file.") f.IntVar(&d.signal, "signal", -1, "sends signal to the sandbox") @@ -147,6 +153,42 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } log.Infof("Heap profile written to %q", d.profileHeap) } + if d.profileGoroutine != "" { + f, err := os.Create(d.profileGoroutine) + if err != nil { + return Errorf(err.Error()) + } + defer f.Close() + + if err := c.Sandbox.GoroutineProfile(f); err != nil { + return Errorf(err.Error()) + } + log.Infof("Goroutine profile written to %q", d.profileGoroutine) + } + if d.profileBlock != "" { + f, err := os.Create(d.profileBlock) + if err != nil { + return Errorf(err.Error()) + } + defer f.Close() + + if err := c.Sandbox.BlockProfile(f); err != nil { + return Errorf(err.Error()) + } + log.Infof("Block profile written to %q", d.profileBlock) + } + if d.profileMutex != "" { + f, err := os.Create(d.profileMutex) + if err != nil { + return Errorf(err.Error()) + } + defer f.Close() + + if err := c.Sandbox.MutexProfile(f); err != nil { + return Errorf(err.Error()) + } + log.Infof("Mutex profile written to %q", d.profileMutex) + } delay := false if d.profileCPU != "" { diff --git a/runsc/cmd/delete.go b/runsc/cmd/delete.go index 30d8164b1..0e4863f50 100644 --- a/runsc/cmd/delete.go +++ b/runsc/cmd/delete.go @@ -19,11 +19,11 @@ import ( "fmt" "os" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) // Delete implements subcommands.Command for the "delete" command. diff --git a/runsc/cmd/do.go b/runsc/cmd/do.go index 9a8a49054..b184bd402 100644 --- a/runsc/cmd/do.go +++ b/runsc/cmd/do.go @@ -27,12 +27,12 @@ import ( "strings" "syscall" - "flag" "github.com/google/subcommands" specs "github.com/opencontainers/runtime-spec/specs-go" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/specutils" ) diff --git a/runsc/cmd/events.go b/runsc/cmd/events.go index 3972e9224..51f6a98ed 100644 --- a/runsc/cmd/events.go +++ b/runsc/cmd/events.go @@ -20,11 +20,11 @@ import ( "os" "time" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) // Events implements subcommands.Command for the "events" command. diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go index d1e99243b..d9a94903e 100644 --- a/runsc/cmd/exec.go +++ b/runsc/cmd/exec.go @@ -27,7 +27,6 @@ import ( "syscall" "time" - "flag" "github.com/google/subcommands" specs "github.com/opencontainers/runtime-spec/specs-go" "gvisor.dev/gvisor/pkg/log" @@ -37,6 +36,7 @@ import ( "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/console" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/specutils" ) diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index 7df7995f0..6e06f3c0f 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -23,7 +23,6 @@ import ( "strings" "syscall" - "flag" "github.com/google/subcommands" specs "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" @@ -32,6 +31,7 @@ import ( "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/unet" "gvisor.dev/gvisor/runsc/boot" + "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/fsgofer" "gvisor.dev/gvisor/runsc/fsgofer/filter" "gvisor.dev/gvisor/runsc/specutils" diff --git a/runsc/cmd/help.go b/runsc/cmd/help.go index 930e8454f..c7d210140 100644 --- a/runsc/cmd/help.go +++ b/runsc/cmd/help.go @@ -18,8 +18,8 @@ import ( "context" "fmt" - "flag" "github.com/google/subcommands" + "gvisor.dev/gvisor/runsc/flag" ) // NewHelp returns a help command for the given commander. diff --git a/runsc/cmd/install.go b/runsc/cmd/install.go index 441c1db0d..2e223e3be 100644 --- a/runsc/cmd/install.go +++ b/runsc/cmd/install.go @@ -23,8 +23,8 @@ import ( "os" "path" - "flag" "github.com/google/subcommands" + "gvisor.dev/gvisor/runsc/flag" ) // Install implements subcommands.Command. diff --git a/runsc/cmd/kill.go b/runsc/cmd/kill.go index 6c1f197a6..8282ea0e0 100644 --- a/runsc/cmd/kill.go +++ b/runsc/cmd/kill.go @@ -21,11 +21,11 @@ import ( "strings" "syscall" - "flag" "github.com/google/subcommands" "golang.org/x/sys/unix" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) // Kill implements subcommands.Command for the "kill" command. diff --git a/runsc/cmd/list.go b/runsc/cmd/list.go index dd2d99a6b..d8d906fe3 100644 --- a/runsc/cmd/list.go +++ b/runsc/cmd/list.go @@ -22,11 +22,11 @@ import ( "text/tabwriter" "time" - "flag" "github.com/google/subcommands" specs "github.com/opencontainers/runtime-spec/specs-go" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) // List implements subcommands.Command for the "list" command for the "list" command. diff --git a/runsc/cmd/pause.go b/runsc/cmd/pause.go index 9c0e92001..6f95a9837 100644 --- a/runsc/cmd/pause.go +++ b/runsc/cmd/pause.go @@ -17,10 +17,10 @@ package cmd import ( "context" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) // Pause implements subcommands.Command for the "pause" command. diff --git a/runsc/cmd/ps.go b/runsc/cmd/ps.go index 45c644f3f..7fb8041af 100644 --- a/runsc/cmd/ps.go +++ b/runsc/cmd/ps.go @@ -18,11 +18,11 @@ import ( "context" "fmt" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/sentry/control" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) // PS implements subcommands.Command for the "ps" command. diff --git a/runsc/cmd/restore.go b/runsc/cmd/restore.go index 7be60cd7d..72584b326 100644 --- a/runsc/cmd/restore.go +++ b/runsc/cmd/restore.go @@ -19,10 +19,10 @@ import ( "path/filepath" "syscall" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/specutils" ) diff --git a/runsc/cmd/resume.go b/runsc/cmd/resume.go index b2df5c640..61a55a554 100644 --- a/runsc/cmd/resume.go +++ b/runsc/cmd/resume.go @@ -17,10 +17,10 @@ package cmd import ( "context" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) // Resume implements subcommands.Command for the "resume" command. diff --git a/runsc/cmd/run.go b/runsc/cmd/run.go index 33f4bc12b..cf41581ad 100644 --- a/runsc/cmd/run.go +++ b/runsc/cmd/run.go @@ -18,10 +18,10 @@ import ( "context" "syscall" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/specutils" ) diff --git a/runsc/cmd/spec.go b/runsc/cmd/spec.go index 344da13ba..8e2b36e85 100644 --- a/runsc/cmd/spec.go +++ b/runsc/cmd/spec.go @@ -20,8 +20,8 @@ import ( "os" "path/filepath" - "flag" "github.com/google/subcommands" + "gvisor.dev/gvisor/runsc/flag" ) var specTemplate = []byte(`{ diff --git a/runsc/cmd/start.go b/runsc/cmd/start.go index 5e9bc53ab..0205fd9f7 100644 --- a/runsc/cmd/start.go +++ b/runsc/cmd/start.go @@ -17,10 +17,10 @@ package cmd import ( "context" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) // Start implements subcommands.Command for the "start" command. diff --git a/runsc/cmd/state.go b/runsc/cmd/state.go index e9f41cbd8..cf2413deb 100644 --- a/runsc/cmd/state.go +++ b/runsc/cmd/state.go @@ -19,11 +19,11 @@ import ( "encoding/json" "os" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) // State implements subcommands.Command for the "state" command. diff --git a/runsc/cmd/statefile.go b/runsc/cmd/statefile.go new file mode 100644 index 000000000..e6f1907da --- /dev/null +++ b/runsc/cmd/statefile.go @@ -0,0 +1,143 @@ +// Copyright 2020 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "context" + "fmt" + "os" + + "github.com/google/subcommands" + "gvisor.dev/gvisor/pkg/state" + "gvisor.dev/gvisor/pkg/state/statefile" + "gvisor.dev/gvisor/runsc/flag" +) + +// Statefile implements subcommands.Command for the "statefile" command. +type Statefile struct { + list bool + get string + key string + output string + html bool +} + +// Name implements subcommands.Command. +func (*Statefile) Name() string { + return "state" +} + +// Synopsis implements subcommands.Command. +func (*Statefile) Synopsis() string { + return "shows information about a statefile" +} + +// Usage implements subcommands.Command. +func (*Statefile) Usage() string { + return `statefile [flags] <statefile>` +} + +// SetFlags implements subcommands.Command. +func (s *Statefile) SetFlags(f *flag.FlagSet) { + f.BoolVar(&s.list, "list", false, "lists the metdata in the statefile.") + f.StringVar(&s.get, "get", "", "extracts the given metadata key.") + f.StringVar(&s.key, "key", "", "the integrity key for the file.") + f.StringVar(&s.output, "output", "", "target to write the result.") + f.BoolVar(&s.html, "html", false, "outputs in HTML format.") +} + +// Execute implements subcommands.Command.Execute. +func (s *Statefile) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { + // Check arguments. + if s.list && s.get != "" { + Fatalf("error: can't specify -list and -get simultaneously.") + } + + // Setup output. + var output = os.Stdout // Default. + if s.output != "" { + f, err := os.OpenFile(s.output, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) + if err != nil { + Fatalf("error opening output: %v", err) + } + defer func() { + if err := f.Close(); err != nil { + Fatalf("error flushing output: %v", err) + } + }() + output = f + } + + // Open the file. + if f.NArg() != 1 { + f.Usage() + return subcommands.ExitUsageError + } + input, err := os.Open(f.Arg(0)) + if err != nil { + Fatalf("error opening input: %v\n", err) + } + + if s.html { + fmt.Fprintf(output, "<html><body>\n") + defer fmt.Fprintf(output, "</body></html>\n") + } + + // Dump the full file? + if !s.list && s.get == "" { + var key []byte + if s.key != "" { + key = []byte(s.key) + } + rc, _, err := statefile.NewReader(input, key) + if err != nil { + Fatalf("error parsing statefile: %v", err) + } + if err := state.PrettyPrint(output, rc, s.html); err != nil { + Fatalf("error printing state: %v", err) + } + return subcommands.ExitSuccess + } + + // Load just the metadata. + metadata, err := statefile.MetadataUnsafe(input) + if err != nil { + Fatalf("error reading metadata: %v", err) + } + + // Is it a single key? + if s.get != "" { + val, ok := metadata[s.get] + if !ok { + Fatalf("metadata key %s: not found", s.get) + } + fmt.Fprintf(output, "%s\n", val) + return subcommands.ExitSuccess + } + + // List all keys. + if s.html { + fmt.Fprintf(output, " <ul>\n") + defer fmt.Fprintf(output, " </ul>\n") + } + for key := range metadata { + if s.html { + fmt.Fprintf(output, " <li>%s</li>\n", key) + } else { + fmt.Fprintf(output, "%s\n", key) + } + } + return subcommands.ExitSuccess +} diff --git a/runsc/cmd/syscalls.go b/runsc/cmd/syscalls.go index fb6c1ab29..7072547be 100644 --- a/runsc/cmd/syscalls.go +++ b/runsc/cmd/syscalls.go @@ -25,9 +25,9 @@ import ( "strconv" "text/tabwriter" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/sentry/kernel" + "gvisor.dev/gvisor/runsc/flag" ) // Syscalls implements subcommands.Command for the "syscalls" command. diff --git a/runsc/cmd/wait.go b/runsc/cmd/wait.go index 046489687..29c0a15f0 100644 --- a/runsc/cmd/wait.go +++ b/runsc/cmd/wait.go @@ -20,10 +20,10 @@ import ( "os" "syscall" - "flag" "github.com/google/subcommands" "gvisor.dev/gvisor/runsc/boot" "gvisor.dev/gvisor/runsc/container" + "gvisor.dev/gvisor/runsc/flag" ) const ( |