From 4c6fa314b3b60aca70fb80401a810e666d03c7d2 Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Tue, 19 Dec 2023 11:51:56 +0000 Subject: [PATCH] Fix emulated cgroups v1 subsystem when running docker-in-docker (#2532) * Fix issues when running with docker-in-docker Signed-off-by: Jorge Prendes * Add the comment to make it understand ease Signed-off-by: utam0k --------- Signed-off-by: Jorge Prendes Signed-off-by: utam0k Co-authored-by: Toru Komatsu --- crates/libcontainer/src/rootfs/mount.rs | 23 +++++++++++++++++++++-- crates/youki/src/observability.rs | 10 +++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/crates/libcontainer/src/rootfs/mount.rs b/crates/libcontainer/src/rootfs/mount.rs index 8d9d82f4..fc333655 100644 --- a/crates/libcontainer/src/rootfs/mount.rs +++ b/crates/libcontainer/src/rootfs/mount.rs @@ -87,7 +87,7 @@ impl Mount { panic!("libcontainer can't run in a Legacy or Hybrid cgroup setup without the v1 feature"); #[cfg(feature = "v1")] self.mount_cgroup_v1(mount, options).map_err(|err| { - tracing::error!("failed to mount cgroup v2: {}", err); + tracing::error!("failed to mount cgroup v1: {}", err); err })? } @@ -171,10 +171,29 @@ impl Mount { tracing::debug!("cgroup mounts: {:?}", host_mounts); // get process cgroups + let ppid = std::os::unix::process::parent_id(); + // The non-zero ppid means that the PID Namespace is not separated. + let ppid = if ppid == 0 { std::process::id() } else { ppid }; + let root_cgroups = Process::new(ppid as i32)?.cgroups()?.0; let process_cgroups: HashMap = Process::myself()? .cgroups()? .into_iter() - .map(|c| (c.controllers.join(","), c.pathname)) + .map(|c| { + let hierarchy = c.hierarchy; + // When youki itself is running inside a container, the cgroup path + // will include the path of pid-1, which needs to be stripped before + // mounting. + let root_pathname = root_cgroups + .iter() + .find(|c| c.hierarchy == hierarchy) + .map(|c| c.pathname.as_ref()) + .unwrap_or(""); + let path = c + .pathname + .strip_prefix(root_pathname) + .unwrap_or(&c.pathname); + (c.controllers.join(","), path.to_owned()) + }) .collect(); tracing::debug!("Process cgroups: {:?}", process_cgroups); diff --git a/crates/youki/src/observability.rs b/crates/youki/src/observability.rs index de171ea8..4015fd08 100644 --- a/crates/youki/src/observability.rs +++ b/crates/youki/src/observability.rs @@ -80,7 +80,15 @@ where let journald = config.systemd_log; let systemd_journald = if journald { - Some(tracing_journald::layer()?.with_syslog_identifier("youki".to_string())) + match tracing_journald::layer() { + Ok(layer) => Some(layer.with_syslog_identifier("youki".to_string())), + Err(err) => { + // Do not fail if we can't open syslog, just print a warning. + // This is the case in, e.g., docker-in-docker. + eprintln!("failed to initialize syslog logging: {:?}", err); + None + } + } } else { None };