mirror of
https://github.com/containers/youki
synced 2024-09-28 15:01:29 +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:
parent
d02acbcc1a
commit
88d26db63f
@ -6,9 +6,12 @@ use libcgroups::common::CgroupSetup::{Hybrid, Legacy};
|
|||||||
#[cfg(feature = "v1")]
|
#[cfg(feature = "v1")]
|
||||||
use libcgroups::common::DEFAULT_CGROUP_ROOT;
|
use libcgroups::common::DEFAULT_CGROUP_ROOT;
|
||||||
use oci_spec::runtime::Spec;
|
use oci_spec::runtime::Spec;
|
||||||
|
use std::fs::{self, File};
|
||||||
|
use std::io::Write;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
const CRIU_CHECKPOINT_LOG_FILE: &str = "dump.log";
|
const CRIU_CHECKPOINT_LOG_FILE: &str = "dump.log";
|
||||||
|
const DESCRIPTORS_JSON: &str = "descriptors.json";
|
||||||
|
|
||||||
impl Container {
|
impl Container {
|
||||||
pub fn checkpoint(&mut self, opts: &CheckpointOptions) -> Result<()> {
|
pub fn checkpoint(&mut self, opts: &CheckpointOptions) -> Result<()> {
|
||||||
@ -88,9 +91,24 @@ impl Container {
|
|||||||
criu.set_work_dir_fd(work_dir.as_raw_fd());
|
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_file(CRIU_CHECKPOINT_LOG_FILE.to_string());
|
||||||
criu.set_log_level(4);
|
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_leave_running(opts.leave_running);
|
||||||
criu.set_ext_unix_sk(opts.ext_unix_sk);
|
criu.set_ext_unix_sk(opts.ext_unix_sk);
|
||||||
criu.set_shell_job(opts.shell_job);
|
criu.set_shell_job(opts.shell_job);
|
||||||
|
@ -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 {
|
let dump_log = match work_path {
|
||||||
Some(wp) => Path::new(wp).join("dump.log"),
|
Some(wp) => Path::new(wp).join("dump.log"),
|
||||||
_ => checkpoint_dir.join("dump.log"),
|
_ => checkpoint_dir.join("dump.log"),
|
||||||
|
Loading…
Reference in New Issue
Block a user