Do not use stream encoders

Marshall the raw objects for the sync pipes so that no new line chars
are left behind in the pipe causing errors.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-01-25 18:15:44 -08:00
parent f36b00aa12
commit 3d8a20bb77
5 changed files with 21 additions and 11 deletions

View File

@ -21,6 +21,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/criurpc" "github.com/opencontainers/runc/libcontainer/criurpc"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/vishvananda/netlink/nl" "github.com/vishvananda/netlink/nl"
) )
@ -968,7 +969,7 @@ func (c *linuxContainer) updateState(process parentProcess) error {
} }
defer f.Close() defer f.Close()
os.Remove(filepath.Join(c.root, "checkpoint")) os.Remove(filepath.Join(c.root, "checkpoint"))
return json.NewEncoder(f).Encode(state) return utils.WriteJSON(f, state)
} }
func (c *linuxContainer) currentStatus() (Status, error) { func (c *linuxContainer) currentStatus() (Status, error) {

View File

@ -5,7 +5,6 @@ package libcontainer
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@ -19,6 +18,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups/systemd" "github.com/opencontainers/runc/libcontainer/cgroups/systemd"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/configs/validate" "github.com/opencontainers/runc/libcontainer/configs/validate"
"github.com/opencontainers/runc/libcontainer/utils"
) )
const ( const (
@ -226,10 +226,7 @@ func (l *LinuxFactory) StartInitialization() (err error) {
// if we have an error during the initialization of the container's init then send it back to the // if we have an error during the initialization of the container's init then send it back to the
// parent process in the form of an initError. // parent process in the form of an initError.
if err != nil { if err != nil {
// ensure that any data sent from the parent is consumed so it doesn't if err := utils.WriteJSON(pipe, newSystemError(err)); err != nil {
// receive ECONNRESET when the child writes to the pipe.
ioutil.ReadAll(pipe)
if err := json.NewEncoder(pipe).Encode(newSystemError(err)); err != nil {
panic(err) panic(err)
} }
} }

View File

@ -3,7 +3,6 @@
package libcontainer package libcontainer
import ( import (
"encoding/json"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -12,6 +11,7 @@ import (
"github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/mount"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/utils"
) )
func newTestRoot() (string, error) { func newTestRoot() (string, error) {
@ -179,5 +179,5 @@ func marshal(path string, v interface{}) error {
return err return err
} }
defer f.Close() defer f.Close()
return json.NewEncoder(f).Encode(v) return utils.WriteJSON(f, v)
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/utils"
) )
type parentProcess interface { type parentProcess interface {
@ -83,7 +84,7 @@ func (p *setnsProcess) start() (err error) {
return newSystemError(err) 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) return newSystemError(err)
} }
if err := syscall.Shutdown(int(p.parentPipe.Fd()), syscall.SHUT_WR); err != nil { if err := syscall.Shutdown(int(p.parentPipe.Fd()), syscall.SHUT_WR); err != nil {
@ -270,7 +271,7 @@ func (p *initProcess) startTime() (string, error) {
func (p *initProcess) sendConfig() error { func (p *initProcess) sendConfig() error {
// send the state to the container's init process then shutdown writes for the parent // 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 { if err := utils.WriteJSON(p.parentPipe, p.config); err != nil {
return err return err
} }
// shutdown writes for the parent side of the pipe // shutdown writes for the parent side of the pipe

View File

@ -3,6 +3,7 @@ package utils
import ( import (
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"encoding/json"
"io" "io"
"path/filepath" "path/filepath"
"syscall" "syscall"
@ -36,10 +37,20 @@ func ResolveRootfs(uncleanRootfs string) (string, error) {
} }
// ExitStatus returns the correct exit status for a process based on if it // 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 { func ExitStatus(status syscall.WaitStatus) int {
if status.Signaled() { if status.Signaled() {
return exitSignalOffset + int(status.Signal()) return exitSignalOffset + int(status.Signal())
} }
return status.ExitStatus() 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
}