summaryrefslogtreecommitdiffhomepage
path: root/runsc/sandbox/sandbox.go
diff options
context:
space:
mode:
Diffstat (limited to 'runsc/sandbox/sandbox.go')
-rw-r--r--runsc/sandbox/sandbox.go140
1 files changed, 50 insertions, 90 deletions
diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go
index 4a4110477..266bc0bdc 100644
--- a/runsc/sandbox/sandbox.go
+++ b/runsc/sandbox/sandbox.go
@@ -173,7 +173,7 @@ func New(conf *config.Config, args *Args) (*Sandbox, error) {
}
// CreateContainer creates a non-root container inside the sandbox.
-func (s *Sandbox) CreateContainer(cid string) error {
+func (s *Sandbox) CreateContainer(cid string, tty *os.File) error {
log.Debugf("Create non-root container %q in sandbox %q, PID: %d", cid, s.ID, s.Pid)
sandboxConn, err := s.sandboxConnect()
if err != nil {
@@ -181,7 +181,16 @@ func (s *Sandbox) CreateContainer(cid string) error {
}
defer sandboxConn.Close()
- if err := sandboxConn.Call(boot.ContainerCreate, &cid, nil); err != nil {
+ var files []*os.File
+ if tty != nil {
+ files = []*os.File{tty}
+ }
+
+ args := boot.CreateArgs{
+ CID: cid,
+ FilePayload: urpc.FilePayload{Files: files},
+ }
+ if err := sandboxConn.Call(boot.ContainerCreate, &args, nil); err != nil {
return fmt.Errorf("creating non-root container %q: %v", cid, err)
}
return nil
@@ -211,11 +220,7 @@ func (s *Sandbox) StartRoot(spec *specs.Spec, conf *config.Config) error {
}
// StartContainer starts running a non-root container inside the sandbox.
-func (s *Sandbox) StartContainer(spec *specs.Spec, conf *config.Config, cid string, goferFiles []*os.File) error {
- for _, f := range goferFiles {
- defer f.Close()
- }
-
+func (s *Sandbox) StartContainer(spec *specs.Spec, conf *config.Config, cid string, stdios, goferFiles []*os.File) error {
log.Debugf("Start non-root container %q in sandbox %q, PID: %d", cid, s.ID, s.Pid)
sandboxConn, err := s.sandboxConnect()
if err != nil {
@@ -223,15 +228,18 @@ func (s *Sandbox) StartContainer(spec *specs.Spec, conf *config.Config, cid stri
}
defer sandboxConn.Close()
- // The payload must container stdin/stdout/stderr followed by gofer
- // files.
- files := append([]*os.File{os.Stdin, os.Stdout, os.Stderr}, goferFiles...)
+ // The payload must contain stdin/stdout/stderr (which may be empty if using
+ // TTY) followed by gofer files.
+ payload := urpc.FilePayload{}
+ payload.Files = append(payload.Files, stdios...)
+ payload.Files = append(payload.Files, goferFiles...)
+
// Start running the container.
args := boot.StartArgs{
Spec: spec,
Conf: conf,
CID: cid,
- FilePayload: urpc.FilePayload{Files: files},
+ FilePayload: payload,
}
if err := sandboxConn.Call(boot.ContainerStart, &args, nil); err != nil {
return fmt.Errorf("starting non-root container %v: %v", spec.Process.Args, err)
@@ -711,6 +719,8 @@ func (s *Sandbox) createSandboxProcess(conf *config.Config, args *Args, startSyn
nextFD++
}
+ _ = nextFD // All FD assignment is finished.
+
if args.Attached {
// Kill sandbox if parent process exits in attached mode.
cmd.SysProcAttr.Pdeathsig = syscall.SIGKILL
@@ -983,7 +993,7 @@ func (s *Sandbox) Stacks() (string, error) {
}
// HeapProfile writes a heap profile to the given file.
-func (s *Sandbox) HeapProfile(f *os.File) error {
+func (s *Sandbox) HeapProfile(f *os.File, delay time.Duration) error {
log.Debugf("Heap profile %q", s.ID)
conn, err := s.sandboxConnect()
if err != nil {
@@ -991,54 +1001,31 @@ func (s *Sandbox) HeapProfile(f *os.File) error {
}
defer conn.Close()
- opts := control.ProfileOpts{
- FilePayload: urpc.FilePayload{
- Files: []*os.File{f},
- },
- }
- if err := conn.Call(boot.HeapProfile, &opts, nil); err != nil {
- return fmt.Errorf("getting sandbox %q heap profile: %v", s.ID, err)
- }
- return nil
-}
-
-// StartCPUProfile start CPU profile writing to the given file.
-func (s *Sandbox) StartCPUProfile(f *os.File) error {
- log.Debugf("CPU profile start %q", s.ID)
- conn, err := s.sandboxConnect()
- if err != nil {
- return err
- }
- defer conn.Close()
-
- opts := control.ProfileOpts{
- FilePayload: urpc.FilePayload{
- Files: []*os.File{f},
- },
+ opts := control.HeapProfileOpts{
+ FilePayload: urpc.FilePayload{Files: []*os.File{f}},
+ Delay: delay,
}
- if err := conn.Call(boot.StartCPUProfile, &opts, nil); err != nil {
- return fmt.Errorf("starting sandbox %q CPU profile: %v", s.ID, err)
- }
- return nil
+ return conn.Call(boot.HeapProfile, &opts, nil)
}
-// StopCPUProfile stops a previously started CPU profile.
-func (s *Sandbox) StopCPUProfile() error {
- log.Debugf("CPU profile stop %q", s.ID)
+// CPUProfile collects a CPU profile.
+func (s *Sandbox) CPUProfile(f *os.File, duration time.Duration) error {
+ log.Debugf("CPU profile %q", s.ID)
conn, err := s.sandboxConnect()
if err != nil {
return err
}
defer conn.Close()
- if err := conn.Call(boot.StopCPUProfile, nil, nil); err != nil {
- return fmt.Errorf("stopping sandbox %q CPU profile: %v", s.ID, err)
+ opts := control.CPUProfileOpts{
+ FilePayload: urpc.FilePayload{Files: []*os.File{f}},
+ Duration: duration,
}
- return nil
+ return conn.Call(boot.CPUProfile, &opts, nil)
}
// BlockProfile writes a block profile to the given file.
-func (s *Sandbox) BlockProfile(f *os.File) error {
+func (s *Sandbox) BlockProfile(f *os.File, duration time.Duration) error {
log.Debugf("Block profile %q", s.ID)
conn, err := s.sandboxConnect()
if err != nil {
@@ -1046,19 +1033,15 @@ func (s *Sandbox) BlockProfile(f *os.File) error {
}
defer conn.Close()
- opts := control.ProfileOpts{
- FilePayload: urpc.FilePayload{
- Files: []*os.File{f},
- },
- }
- if err := conn.Call(boot.BlockProfile, &opts, nil); err != nil {
- return fmt.Errorf("getting sandbox %q block profile: %v", s.ID, err)
+ opts := control.BlockProfileOpts{
+ FilePayload: urpc.FilePayload{Files: []*os.File{f}},
+ Duration: duration,
}
- return nil
+ return conn.Call(boot.BlockProfile, &opts, nil)
}
// MutexProfile writes a mutex profile to the given file.
-func (s *Sandbox) MutexProfile(f *os.File) error {
+func (s *Sandbox) MutexProfile(f *os.File, duration time.Duration) error {
log.Debugf("Mutex profile %q", s.ID)
conn, err := s.sandboxConnect()
if err != nil {
@@ -1066,50 +1049,27 @@ func (s *Sandbox) MutexProfile(f *os.File) error {
}
defer conn.Close()
- opts := control.ProfileOpts{
- FilePayload: urpc.FilePayload{
- Files: []*os.File{f},
- },
- }
- if err := conn.Call(boot.MutexProfile, &opts, nil); err != nil {
- return fmt.Errorf("getting sandbox %q mutex profile: %v", s.ID, err)
- }
- return nil
-}
-
-// StartTrace start trace writing to the given file.
-func (s *Sandbox) StartTrace(f *os.File) error {
- log.Debugf("Trace start %q", s.ID)
- conn, err := s.sandboxConnect()
- if err != nil {
- return err
- }
- defer conn.Close()
-
- opts := control.ProfileOpts{
- FilePayload: urpc.FilePayload{
- Files: []*os.File{f},
- },
+ opts := control.MutexProfileOpts{
+ FilePayload: urpc.FilePayload{Files: []*os.File{f}},
+ Duration: duration,
}
- if err := conn.Call(boot.StartTrace, &opts, nil); err != nil {
- return fmt.Errorf("starting sandbox %q trace: %v", s.ID, err)
- }
- return nil
+ return conn.Call(boot.MutexProfile, &opts, nil)
}
-// StopTrace stops a previously started trace.
-func (s *Sandbox) StopTrace() error {
- log.Debugf("Trace stop %q", s.ID)
+// Trace collects an execution trace.
+func (s *Sandbox) Trace(f *os.File, duration time.Duration) error {
+ log.Debugf("Trace %q", s.ID)
conn, err := s.sandboxConnect()
if err != nil {
return err
}
defer conn.Close()
- if err := conn.Call(boot.StopTrace, nil, nil); err != nil {
- return fmt.Errorf("stopping sandbox %q trace: %v", s.ID, err)
+ opts := control.TraceProfileOpts{
+ FilePayload: urpc.FilePayload{Files: []*os.File{f}},
+ Duration: duration,
}
- return nil
+ return conn.Call(boot.Trace, &opts, nil)
}
// ChangeLogging changes logging options.