1
0
Fork 0
mirror of https://github.com/containers/youki synced 2024-05-27 01:46:08 +02:00

Add descriptors.json when creating checkpoint

runc as well as crun create a file called descriptors.json in the
checkpoint directory. descriptors.json contains a list of how the FDs
0, 1, 2 are connected before checkpointing:

$ cat descriptors.json # created by runc in this case
["/dev/null","pipe:[230688]","pipe:[230689]"]

With this information the FDs can be reconnected correctly during
restore.

With this commit is it possible to do:

$ youki run container
$ youki checkpointt container
$ runc restore container

Now the checkpoint is in a format that can be handled by other container
runtimes.

Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
Adrian Reber 2023-01-23 07:40:23 +00:00
parent d02acbcc1a
commit 88d26db63f
No known key found for this signature in database
GPG Key ID: 82C9378ED3C4906A
2 changed files with 26 additions and 1 deletions

View File

@ -6,9 +6,12 @@ use libcgroups::common::CgroupSetup::{Hybrid, Legacy};
#[cfg(feature = "v1")]
use libcgroups::common::DEFAULT_CGROUP_ROOT;
use oci_spec::runtime::Spec;
use std::fs::{self, File};
use std::io::Write;
use std::os::unix::io::AsRawFd;
const CRIU_CHECKPOINT_LOG_FILE: &str = "dump.log";
const DESCRIPTORS_JSON: &str = "descriptors.json";
impl Container {
pub fn checkpoint(&mut self, opts: &CheckpointOptions) -> Result<()> {
@ -88,9 +91,24 @@ impl Container {
criu.set_work_dir_fd(work_dir.as_raw_fd());
}
let pid: i32 = self.pid().unwrap().into();
// Remember original stdin, stdout, stderr for container restore.
let mut descriptors = Vec::new();
for n in 0..3 {
let link_path = match fs::read_link(format!("/proc/{}/fd/{}", pid, n)) {
Ok(lp) => lp.into_os_string().into_string().unwrap(),
Err(..) => "/dev/null".to_string(),
};
descriptors.push(link_path);
}
let descriptors_json_path = opts.image_path.join(DESCRIPTORS_JSON);
let mut descriptors_json = File::create(descriptors_json_path)?;
write!(descriptors_json, "{}", serde_json::to_string(&descriptors)?)?;
criu.set_log_file(CRIU_CHECKPOINT_LOG_FILE.to_string());
criu.set_log_level(4);
criu.set_pid(self.pid().unwrap().into());
criu.set_pid(pid);
criu.set_leave_running(opts.leave_running);
criu.set_ext_unix_sk(opts.ext_unix_sk);
criu.set_shell_job(opts.shell_job);

View File

@ -144,6 +144,13 @@ fn checkpoint(
));
}
if !Path::new(&checkpoint_dir.join("descriptors.json")).exists() {
return TestResult::Failed(anyhow::anyhow!(
"resulting checkpoint does not seem to be complete. {:?}/descriptors.json is missing",
&checkpoint_dir,
));
}
let dump_log = match work_path {
Some(wp) => Path::new(wp).join("dump.log"),
_ => checkpoint_dir.join("dump.log"),