Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}