Skip to content

Commit

Permalink
Merge pull request #515 from crosbymichael/readall
Browse files Browse the repository at this point in the history
Do not use stream encoders for pipe communication
  • Loading branch information
crosbymichael committed Jan 26, 2016
2 parents 32ad3ba + ddcee3c commit 7cd384c
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 21 deletions.
3 changes: 2 additions & 1 deletion libcontainer/container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/criurpc"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/vishvananda/netlink/nl"
)

Expand Down Expand Up @@ -964,7 +965,7 @@ func (c *linuxContainer) saveState(s *State) error {
return err
}
defer f.Close()
return json.NewEncoder(f).Encode(s)
return utils.WriteJSON(f, s)
}

func (c *linuxContainer) deleteState() error {
Expand Down
7 changes: 4 additions & 3 deletions libcontainer/factory_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/configs/validate"
"github.com/opencontainers/runc/libcontainer/utils"
)

const (
Expand Down Expand Up @@ -235,15 +236,15 @@ func (l *LinuxFactory) StartInitialization() (err error) {
if err != nil {
if _, ok := i.(*linuxStandardInit); ok {
// Synchronisation only necessary for standard init.
if err := json.NewEncoder(pipe).Encode(procError); err != nil {
if err := utils.WriteJSON(pipe, syncT{procError}); err != nil {
panic(err)
}
}
if err := json.NewEncoder(pipe).Encode(newSystemError(err)); err != nil {
if err := utils.WriteJSON(pipe, newSystemError(err)); err != nil {
panic(err)
}
} else {
if err := json.NewEncoder(pipe).Encode(procStart); err != nil {
if err := utils.WriteJSON(pipe, syncT{procStart}); err != nil {
panic(err)
}
}
Expand Down
4 changes: 2 additions & 2 deletions libcontainer/factory_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
package libcontainer

import (
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
Expand All @@ -12,6 +11,7 @@ import (

"github.com/docker/docker/pkg/mount"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/utils"
)

func newTestRoot() (string, error) {
Expand Down Expand Up @@ -179,5 +179,5 @@ func marshal(path string, v interface{}) error {
return err
}
defer f.Close()
return json.NewEncoder(f).Encode(v)
return utils.WriteJSON(f, v)
}
4 changes: 4 additions & 0 deletions libcontainer/generic_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ const (
procRun
)

type syncT struct {
Type syncType `json:"type"`
}

var errorTemplate = template.Must(template.New("error").Parse(`Timestamp: {{.Timestamp}}
Code: {{.ECode}}
{{if .Message }}
Expand Down
7 changes: 3 additions & 4 deletions libcontainer/init_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,16 @@ func finalizeNamespace(config *initConfig) error {
// indicate that it is cleared to Exec.
func syncParentReady(pipe io.ReadWriter) error {
// Tell parent.
if err := json.NewEncoder(pipe).Encode(procReady); err != nil {
if err := utils.WriteJSON(pipe, syncT{procReady}); err != nil {
return err
}

// Wait for parent to give the all-clear.
var procSync syncType
var procSync syncT
if err := json.NewDecoder(pipe).Decode(&procSync); err != nil {
if err == io.EOF {
return fmt.Errorf("parent closed synchronisation channel")
}
if procSync != procRun {
if procSync.Type != procRun {
return fmt.Errorf("invalid synchronisation flag from parent")
}
}
Expand Down
16 changes: 6 additions & 10 deletions libcontainer/process_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/utils"
)

type parentProcess interface {
Expand Down Expand Up @@ -84,7 +85,7 @@ func (p *setnsProcess) start() (err error) {
return newSystemError(err)
}
}
if err := json.NewEncoder(p.parentPipe).Encode(p.config); err != nil {
if err := utils.WriteJSON(p.parentPipe, p.config); err != nil {
return newSystemError(err)
}

Expand Down Expand Up @@ -231,9 +232,8 @@ func (p *initProcess) start() (err error) {
if err := p.sendConfig(); err != nil {
return newSystemError(err)
}

var (
procSync syncType
procSync syncT
sentRun bool
ierr *genericError
)
Expand All @@ -246,16 +246,15 @@ loop:
}
return newSystemError(err)
}

switch procSync {
switch procSync.Type {
case procStart:
break loop
case procReady:
if err := p.manager.Set(p.config.Config); err != nil {
return newSystemError(err)
}
// Sync with child.
if err := json.NewEncoder(p.parentPipe).Encode(procRun); err != nil {
if err := utils.WriteJSON(p.parentPipe, syncT{procRun}); err != nil {
return newSystemError(err)
}
sentRun = true
Expand Down Expand Up @@ -317,10 +316,7 @@ func (p *initProcess) startTime() (string, error) {

func (p *initProcess) sendConfig() error {
// send the state to the container's init process then shutdown writes for the parent
if err := json.NewEncoder(p.parentPipe).Encode(p.config); err != nil {
return err
}
return nil
return utils.WriteJSON(p.parentPipe, p.config)
}

func (p *initProcess) createNetworkInterfaces() error {
Expand Down
13 changes: 12 additions & 1 deletion libcontainer/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package utils
import (
"crypto/rand"
"encoding/hex"
"encoding/json"
"io"
"path/filepath"
"syscall"
Expand Down Expand Up @@ -36,10 +37,20 @@ func ResolveRootfs(uncleanRootfs string) (string, error) {
}

// ExitStatus returns the correct exit status for a process based on if it
// was signaled or exited cleanly.
// was signaled or exited cleanly
func ExitStatus(status syscall.WaitStatus) int {
if status.Signaled() {
return exitSignalOffset + int(status.Signal())
}
return status.ExitStatus()
}

// WriteJSON writes the provided struct v to w using standard json marshaling
func WriteJSON(w io.Writer, v interface{}) error {
data, err := json.Marshal(v)
if err != nil {
return err
}
_, err = w.Write(data)
return err
}

0 comments on commit 7cd384c

Please sign in to comment.