-
Notifications
You must be signed in to change notification settings - Fork 317
WIP: Add Checkpoint and Restore support to libcontainer #479
Conversation
@@ -96,6 +96,9 @@ type Config struct { | |||
// ReadonlyPaths specifies paths within the container's rootfs to remount as read-only | |||
// so that these files prevent any writes. | |||
ReadonlyPaths []string `json:"readonly_paths"` | |||
|
|||
// Container's standard descriptors (std{in,out,err}), needed for checkpoint and restore | |||
StdFds [3]string `json:"ext_pipes,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit: Could the json property be called something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mrunalp
Sure, any suggestions? The name ext_pipes was chosen because the standard file descriptors are actually external pipes but I am open to better suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SaiedKazemi I was thinking that the name of the exported field and the json tag be similar like elsewhere in the code. If the name is StdFds, then maybe std_fds for the json tag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, +1. or rename StdFds to ExtPipes :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. Will do.
Supercool. |
so cool so cool so cool, can't contain myself On Tue, Mar 24, 2015 at 1:49 PM, Alexander Morozov <[email protected]
|
if err := os.Mkdir(dir, 0655); err != nil && !os.IsExist(err) { | ||
return err | ||
} | ||
args := []string{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we have hashed this before :) Should we check for the presence of a minimum version of criu that supports all the flags or maybe just document it, so distributions know what version they need?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the flags have been there for many years and we haven't introduced new flags in a long time. But if someone is running an old version of CRIU that doesn't support a specific flag, CRIU will print an error message and exit -- no damage done. That said, we can certainly add code to do version check every time but I really think it'd be an overkill :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SaiedKazemi That is fair. I think if we just document a minimum version, that will be helpful :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for validating compatibility.
👍 |
Looking forward... 👍 |
@@ -249,6 +257,124 @@ func (c *linuxContainer) NotifyOOM() (<-chan struct{}, error) { | |||
return notifyOnOOM(c.cgroupManager.GetPaths()) | |||
} | |||
|
|||
// XXX debug support, remove when debugging done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get rid of all the debug code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vishh
Since we're still debugging, it makes a lot easier to add additional command line options when invoking CRIU through the environment. Otherwise, we need to edit and recompile source for every little change in the options. I will remove it soon.
Just for an FYI, |
|
||
// XXX This doesn't really belong here as our caller should have | ||
// already set up root (including devices) and mounted it. | ||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete dead code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vishh
Will do.
I'm interested in a slightly different use case than possible with the way this PR would work. Specifically, I want to be able to checkpoint a container without stopping it, and then later be able to either "roll back" the container to that point in time or alternatively spin up a new container from that checkpoint. Is there any interest in the idea of allowing you to specify an explicit path to checkpoint to and restore from (and, additionally, flags like --leave-running). |
I'm trying to get this pull request running and having some trouble. What I've tried so far is to build libcontainer (with it's Dockerfile, and the addition of criu to that Dockerfile), and run the following test:
followed by https://gist.github.com/boucher/d2539bcaa1311c5d5f5c Any suggestions? Or, is there a better way to test this? (edit: I should note that I tried both master and the 1.5 stable branch of criu) |
Just wanted to follow up in this thread that I was able to get this PR running outside of Docker, directly on a linux host, but haven't yet been able to get it working inside of Docker. |
|
||
// cmd.Wait() waits cmd.goroutines which are used for proxying file descriptors. | ||
// Here we want to wait only the CRIU process. | ||
st, err := cmd.Process.Wait() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm working on getting this branch up and running in Docker, but I'm a bit unsure about what to do here. Because we're not passing the -d flag to criu, this Wait will actually just wait forever -- that's fine in the sort of direct nsinit resume an interactive container case (which I had used to test this branch), but it doesn't work when dealing with the Docker daemon. Should this be a configurable flag we're passing in, or should the wait be handled at the nsinit level and not here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, here is a mistake. I've fixed it in #486
|
||
switch { | ||
case notify.GetScript() == "post-dump": | ||
f, err := os.Create(filepath.Join(c.root, "checkpoint")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the purpose of this file now just to be a flag that things are checkpointed? (Previously, this is where things were being stored if no directory was specified)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@boucher Yes, it's a flag. It's used in currentStatus() to determine the Checkpointed state.
I'm getting this error on some restore attempts when running this branch:
I added a log in criuSwrk to print all the opts right before actually sending them, and other than the actual directory paths I seem to have two identical set of options that work and don't work (though the underlying container isn't the same, but the error message seems to imply a communication failure not an actual restore failure). I'm running in two different VMs so I'm going to try and narrow down the differences some more to figure out what's going on but I figured I'd post this here to see if there were any ideas. |
@boucher I think we use too small buffer in CRIU. Probably we need to allocate it dinamically. Could you try out this patch for criu?
|
The last issue is a criu bug: http://lists.openvz.org/pipermail/criu/2015-April/019928.html |
@crosbymichael @SaiedKazemi @LK4D4 @mrunalp @vmarmol I think I've fixed all known issue. Maybe it's time to merge this branch? |
@avagin @crosbymichael @LK4D4 @vmarmol |
Ok, so I should be able to build this branch, and everything with work flawlessly the first time? |
In a future we may want to have more external descriptors. Signed-off-by: Andrey Vagin <[email protected]>
Docker-DCO-1.1-Signed-off-by: Ross Boucher <[email protected]> (github: boucher)
Signed-off-by: Andrey Vagin <[email protected]>
…a const. Docker-DCO-1.1-Signed-off-by: Ross Boucher <[email protected]> (github: boucher)
Docker-DCO-1.1-Signed-off-by: Ross Boucher <[email protected]> (github: boucher)
container.Checkpoint() doesn't clear c.initProcess and it's used on restore. Signed-off-by: Andrew Vagin <[email protected]>
…equiring that one already exists. Docker-DCO-1.1-Signed-off-by: Ross Boucher <[email protected]> (github: boucher)
Docker-DCO-1.1-Signed-off-by: Ross Boucher <[email protected]> (github: boucher)
Adds iptables as a requirement of criu in the Dockerfile. Docker-DCO-1.1-Signed-off-by: Ross Boucher <[email protected]> (github: boucher)
The format of criu version is X.Y[.Z]. The current code can not parse X.Y, because scanf returns the "input does not match format" error. Signed-off-by: Andrey Vagin <[email protected]>
Signed-off-by: Michael Crosby <[email protected]>
Docker-DCO-1.1-Signed-off-by: Ross Boucher <[email protected]> (github: boucher)
This is really exciting work! Is there any update on the status of this PR? |
README example for using checkpoint/restore.
I'm getting the error: nsinit checkpoint --image-path /tmp/checkpoint
criu failed: type DUMP errno 0 |
criu is compiled via the v1.5.2 tag and running on ubuntu 15.04 (the new LTS) |
Can you send the dump log? On Thursday, May 21, 2015, Michael Crosby [email protected] wrote:
Sent from Gmail Mobile |
@boucher i don't have the dump.log in the image dir? is it located somewhere else? |
@crosbymichael Could you attache a strace log? |
@crosbymichael this log doesn't contain "criu failed:...". dump.log is saved in /var/run/nsinit/nsinit/criu.work/ ''' |
ok, it was a setuid issue with my binary |
LGTM |
thanks @avagin @boucher @SaiedKazemi |
WIP: Add Checkpoint and Restore support to libcontainer
This is a work in progress PR so that we can move the discussion around this work into a PR to help move things along and get other people involved.
We are trying to get
nsinit
work as an easy way to test but the first class support should be for using it from a daemon such as docker.Any more work can be done on the
criu
branch of this repo via pull requests.