[lxc-devel] [crio-lxc/master] Fix container start sequence

hallyn on Github lxc-bot at linuxcontainers.org
Fri Apr 19 18:09:59 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 1105 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190419/1f16da8e/attachment.bin>
-------------- next part --------------
From 7c4744ac1da8e73824e9368d7b9104c0ca4fdc7e Mon Sep 17 00:00:00 2001
From: Serge Hallyn <shallyn at cisco.com>
Date: Fri, 19 Apr 2019 13:06:57 -0500
Subject: [PATCH] Fix container start sequence

Warning!  Major hack alert.

When we create a crio-lxc container, we start the lxc container to
wait for the syncfifo.  The crio-lxc container isn't really started
until the fifo is written to.

So we can't just use c.Running() to tell us that the crio-lxc container
is running.

Ideally we could add a 'criolxc.state' key in the container config.
Lxc would happily ignore that.  However, we cannot use the lxc api
to do that because it doesn't know about the keys.  And if we do it
ourselves, then we need to worry about locking.

So, add a pre-start hook of /bin/true to the config file when the
syncfifo is unlocked.  If anyone wants to set /bin/true as a real
pre-start hook, come talk to me.

Other ideas are definitely welcome!

Signed-off-by: Serge Hallyn <shallyn at cisco.com>
---
 cmd/create.go |  8 +++++++-
 cmd/delete.go |  2 +-
 cmd/start.go  | 29 +++++++++++++++++++++++++++--
 cmd/state.go  |  2 +-
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/cmd/create.go b/cmd/create.go
index 6c52d33..51a9949 100644
--- a/cmd/create.go
+++ b/cmd/create.go
@@ -10,6 +10,7 @@ import (
 	"path"
 	"path/filepath"
 	"strings"
+	"time"
 
 	"github.com/apex/log"
 	"github.com/opencontainers/runtime-spec/specs-go"
@@ -207,6 +208,11 @@ func startContainer(c *lxc.Container, spec *specs.Spec) error {
 
 	cmdErr := cmd.Start()
 
-	return cmdErr
+	if cmdErr == nil {
+		if !c.Wait(lxc.RUNNING, 30*time.Second) {
+			cmdErr = fmt.Errorf("Container failed to initialize")
+		}
+	}
 
+	return cmdErr
 }
diff --git a/cmd/delete.go b/cmd/delete.go
index 21f366d..91b6ee1 100644
--- a/cmd/delete.go
+++ b/cmd/delete.go
@@ -48,7 +48,7 @@ func doDelete(ctx *cli.Context) error {
 
 	}
 
-	if c.Running() {
+	if c.Running() && checkHackyPreStart(c) == "started" {
 		return fmt.Errorf("container '%s' is running, cannot delete.", containerID)
 	}
 
diff --git a/cmd/start.go b/cmd/start.go
index 275ea77..7e248a2 100644
--- a/cmd/start.go
+++ b/cmd/start.go
@@ -23,6 +23,27 @@ starts <containerID>
 `,
 }
 
+func checkHackyPreStart(c *lxc.Container) string {
+	hooks := c.ConfigItem("lxc.hook.pre-start")
+	for _, h := range hooks {
+		if h == "/bin/true" {
+			return "started"
+		}
+	}
+	return "prestart"
+}
+
+func setHackyPreStart(c *lxc.Container) {
+	err := c.SetConfigItem("lxc.hook.pre-start", "/bin/true")
+	if err != nil {
+		log.Warnf("Failed to set \"container started\" indicator: %v", err)
+	}
+	err = c.SaveConfigFile(filepath.Join(LXC_PATH, c.Name(), "config"))
+	if err != nil {
+		log.Warnf("Failed to save \"container started\" indicator: %v", err)
+	}
+}
+
 func doStart(ctx *cli.Context) error {
 	containerID := ctx.Args().Get(0)
 	if len(containerID) == 0 {
@@ -37,10 +58,14 @@ func doStart(ctx *cli.Context) error {
 	}
 	defer c.Release()
 	log.Infof("checking if running")
-	if c.Running() {
-		return fmt.Errorf("'%s' is already running", containerID)
+	if !c.Running() {
+		return fmt.Errorf("'%s' is not ready", containerID)
+	}
+	if checkHackyPreStart(c) == "started" {
+		return fmt.Errorf("'%s' already running", containerID)
 	}
 	log.Infof("not running, can start")
+	setHackyPreStart(c)
 	fifoPath := filepath.Join(LXC_PATH, containerID, "syncfifo")
 	log.Infof("opening fifo '%s'", fifoPath)
 	f, err := os.OpenFile(fifoPath, os.O_RDWR, 0)
diff --git a/cmd/state.go b/cmd/state.go
index 955acb6..5e8af42 100644
--- a/cmd/state.go
+++ b/cmd/state.go
@@ -55,7 +55,7 @@ func doState(ctx *cli.Context) error {
 	// https://github.com/opencontainers/runtime-spec/blob/v1.0.0-rc4/runtime.md#state
 	// it means "the container process has neither exited nor executed the user-specified program"
 	status := "stopped"
-	if c.Running() {
+	if c.Running() && checkHackyPreStart(c) == "started" {
 		status = "running"
 	}
 	pid := 0


More information about the lxc-devel mailing list