Docker-DCO-1.1-Signed-off-by: Guillaume J. Charmes <guillaume.charmes@docker.com> (github: creack)
| ... | ... |
@@ -22,16 +22,20 @@ func execCommand(container *libcontainer.Container, args []string) (int, error) |
| 22 | 22 |
return -1, err |
| 23 | 23 |
} |
| 24 | 24 |
|
| 25 |
- command := createCommand(container, console, args) |
|
| 26 | 25 |
// create a pipe so that we can syncronize with the namespaced process and |
| 27 | 26 |
// pass the veth name to the child |
| 28 |
- inPipe, err := command.StdinPipe() |
|
| 27 |
+ r, w, err := os.Pipe() |
|
| 29 | 28 |
if err != nil {
|
| 30 | 29 |
return -1, err |
| 31 | 30 |
} |
| 31 |
+ system.UsetCloseOnExec(r.Fd()) |
|
| 32 |
+ |
|
| 33 |
+ command := createCommand(container, console, r.Fd(), args) |
|
| 34 |
+ |
|
| 32 | 35 |
if err := command.Start(); err != nil {
|
| 33 | 36 |
return -1, err |
| 34 | 37 |
} |
| 38 |
+ |
|
| 35 | 39 |
if err := writePidFile(command); err != nil {
|
| 36 | 40 |
command.Process.Kill() |
| 37 | 41 |
return -1, err |
| ... | ... |
@@ -52,11 +56,11 @@ func execCommand(container *libcontainer.Container, args []string) (int, error) |
| 52 | 52 |
if err != nil {
|
| 53 | 53 |
return -1, err |
| 54 | 54 |
} |
| 55 |
- sendVethName(vethPair, inPipe) |
|
| 55 |
+ sendVethName(vethPair, w) |
|
| 56 | 56 |
} |
| 57 | 57 |
|
| 58 | 58 |
// Sync with child |
| 59 |
- inPipe.Close() |
|
| 59 |
+ w.Close() |
|
| 60 | 60 |
|
| 61 | 61 |
go io.Copy(os.Stdout, master) |
| 62 | 62 |
go io.Copy(master, os.Stdin) |
| ... | ... |
@@ -163,8 +167,8 @@ func deletePidFile() error {
|
| 163 | 163 |
// createCommand will return an exec.Cmd with the Cloneflags set to the proper namespaces |
| 164 | 164 |
// defined on the container's configuration and use the current binary as the init with the |
| 165 | 165 |
// args provided |
| 166 |
-func createCommand(container *libcontainer.Container, console string, args []string) *exec.Cmd {
|
|
| 167 |
- command := exec.Command("nsinit", append([]string{"-console", console, "init"}, args...)...)
|
|
| 166 |
+func createCommand(container *libcontainer.Container, console string, pipe uintptr, args []string) *exec.Cmd {
|
|
| 167 |
+ command := exec.Command("nsinit", append([]string{"-console", console, "-pipe", fmt.Sprint(pipe), "init"}, args...)...)
|
|
| 168 | 168 |
command.SysProcAttr = &syscall.SysProcAttr{
|
| 169 | 169 |
Cloneflags: uintptr(getNamespaceFlags(container.Namespaces)), |
| 170 | 170 |
} |
| ... | ... |
@@ -8,20 +8,21 @@ import ( |
| 8 | 8 |
"github.com/dotcloud/docker/pkg/libcontainer/capabilities" |
| 9 | 9 |
"github.com/dotcloud/docker/pkg/libcontainer/network" |
| 10 | 10 |
"github.com/dotcloud/docker/pkg/system" |
| 11 |
+ "io" |
|
| 11 | 12 |
"io/ioutil" |
| 12 | 13 |
"os" |
| 13 | 14 |
"path/filepath" |
| 14 | 15 |
"syscall" |
| 15 | 16 |
) |
| 16 | 17 |
|
| 17 |
-func initCommand(container *libcontainer.Container, console string, args []string) error {
|
|
| 18 |
+func initCommand(container *libcontainer.Container, console string, pipe io.ReadCloser, args []string) error {
|
|
| 18 | 19 |
rootfs, err := resolveRootfs() |
| 19 | 20 |
if err != nil {
|
| 20 | 21 |
return err |
| 21 | 22 |
} |
| 22 | 23 |
|
| 23 | 24 |
// We always read this as it is a way to sync with the parent as well |
| 24 |
- tempVethName, err := getVethName() |
|
| 25 |
+ tempVethName, err := getVethName(pipe) |
|
| 25 | 26 |
if err != nil {
|
| 26 | 27 |
return err |
| 27 | 28 |
} |
| ... | ... |
@@ -164,8 +165,10 @@ func setupVethNetwork(config *libcontainer.Network, tempVethName string) error {
|
| 164 | 164 |
// getVethName reads from Stdin the temp veth name |
| 165 | 165 |
// sent by the parent processes after the veth pair |
| 166 | 166 |
// has been created and setup |
| 167 |
-func getVethName() (string, error) {
|
|
| 168 |
- data, err := ioutil.ReadAll(os.Stdin) |
|
| 167 |
+func getVethName(pipe io.ReadCloser) (string, error) {
|
|
| 168 |
+ defer pipe.Close() |
|
| 169 |
+ |
|
| 170 |
+ data, err := ioutil.ReadAll(pipe) |
|
| 169 | 171 |
if err != nil {
|
| 170 | 172 |
return "", fmt.Errorf("error reading from stdin %s", err)
|
| 171 | 173 |
} |
| ... | ... |
@@ -18,6 +18,7 @@ var ( |
| 18 | 18 |
|
| 19 | 19 |
func main() {
|
| 20 | 20 |
console := flag.String("console", "", "Console (pty slave) name")
|
| 21 |
+ pipeFd := flag.Int("pipe", 0, "sync pipe fd")
|
|
| 21 | 22 |
flag.Parse() |
| 22 | 23 |
|
| 23 | 24 |
container, err := loadContainer() |
| ... | ... |
@@ -50,7 +51,7 @@ func main() {
|
| 50 | 50 |
if flag.NArg() < 2 {
|
| 51 | 51 |
log.Fatal(ErrWrongArguments) |
| 52 | 52 |
} |
| 53 |
- if err := initCommand(container, *console, flag.Args()[1:]); err != nil {
|
|
| 53 |
+ if err := initCommand(container, *console, os.NewFile(uintptr(*pipeFd), "pipe"), flag.Args()[1:]); err != nil {
|
|
| 54 | 54 |
log.Fatal(err) |
| 55 | 55 |
} |
| 56 | 56 |
default: |