| 1 | Patch-Source: https://github.com/youki-dev/youki/pull/3146
|
| 2 | --
|
| 3 | From d8198befdf89e33e28425cc334a342a73e725043 Mon Sep 17 00:00:00 2001
|
| 4 | From: Michal Rostecki <[email protected]>
|
| 5 | Date: Fri, 11 Apr 2025 07:41:31 +0200
|
| 6 | Subject: [PATCH] libcontainer: Skip cgroup creation for rootless containers
|
| 7 | with cgroupfs
|
| 8 |
|
| 9 | Creating cgroups with cgroupfs as non-root is not possible. Before this
|
| 10 | change, we used to enforce systemd as a cgroup manager for all rootless
|
| 11 | containers, but that prevents the usage of rootless youki on systems
|
| 12 | wuthout systemd. To make such usage possible, raise a warning and skip
|
| 13 | cgroup-related activities instead. That matches the behavior of crun
|
| 14 | (containers/crun#97).
|
| 15 |
|
| 16 | Fixes #3144
|
| 17 |
|
| 18 | Signed-off-by: Michal Rostecki <[email protected]>
|
| 19 | ---
|
| 20 | crates/libcgroups/src/common.rs | 19 ++++--
|
| 21 | .../src/container/builder_impl.rs | 14 +++--
|
| 22 | .../libcontainer/src/container/container.rs | 9 +++
|
| 23 | .../src/container/container_delete.rs | 5 +-
|
| 24 | .../src/container/container_events.rs | 37 ++++++-----
|
| 25 | .../src/container/container_kill.rs | 60 ++++++++++--------
|
| 26 | .../src/container/container_pause.rs | 5 +-
|
| 27 | .../src/container/container_resume.rs | 5 +-
|
| 28 | .../src/container/init_builder.rs | 1 +
|
| 29 | crates/libcontainer/src/container/state.rs | 3 +
|
| 30 | .../process/container_intermediate_process.rs | 12 ++--
|
| 31 | crates/youki/src/commands/mod.rs | 3 +-
|
| 32 | crates/youki/src/commands/ps.rs | 62 ++++++++++---------
|
| 33 | crates/youki/src/commands/update.rs | 42 +++++++------
|
| 34 | 14 files changed, 163 insertions(+), 114 deletions(-)
|
| 35 |
|
| 36 | diff --git a/crates/libcgroups/src/common.rs b/crates/libcgroups/src/common.rs
|
| 37 | index 76bcc14f00..9148326d76 100644
|
| 38 | |
| 39 | |
| 40 | @@ -330,6 +330,7 @@ pub enum CreateCgroupSetupError {
|
| 41 | pub struct CgroupConfig {
|
| 42 | pub cgroup_path: PathBuf,
|
| 43 | pub systemd_cgroup: bool,
|
| 44 | + pub rootless_container: bool,
|
| 45 | pub container_name: String,
|
| 46 | }
|
| 47 |
|
| 48 | @@ -338,7 +339,13 @@ pub struct CgroupConfig {
|
| 49 | pub fn create_cgroup_manager_with_root(
|
| 50 | root_path: Option<&Path>,
|
| 51 | config: CgroupConfig,
|
| 52 | -) -> Result<AnyCgroupManager, CreateCgroupSetupError> {
|
| 53 | +) -> Result<Option<AnyCgroupManager>, CreateCgroupSetupError> {
|
| 54 | + // Creating cgroups with cgroupfs as non-root is not possible.
|
| 55 | + if !config.systemd_cgroup && config.rootless_container {
|
| 56 | + tracing::warn!("cannot configure rootless cgroup using the cgroupfs manager");
|
| 57 | + return Ok(None);
|
| 58 | + }
|
| 59 | +
|
| 60 | let root = match root_path {
|
| 61 | Some(p) => p,
|
| 62 | None => Path::new(DEFAULT_CGROUP_ROOT),
|
| 63 | @@ -353,24 +360,24 @@ pub fn create_cgroup_manager_with_root(
|
| 64 |
|
| 65 | match cgroup_setup {
|
| 66 | CgroupSetup::Legacy | CgroupSetup::Hybrid => {
|
| 67 | - Ok(create_v1_cgroup_manager(cgroup_path)?.any())
|
| 68 | + Ok(Some(create_v1_cgroup_manager(cgroup_path)?.any()))
|
| 69 | }
|
| 70 | CgroupSetup::Unified => {
|
| 71 | // ref https://github.com/opencontainers/runtime-spec/blob/main/config-linux.md#cgroups-path
|
| 72 | if cgroup_path.is_absolute() || !config.systemd_cgroup {
|
| 73 | - return Ok(create_v2_cgroup_manager(root, cgroup_path)?.any());
|
| 74 | + return Ok(Some(create_v2_cgroup_manager(root, cgroup_path)?.any()));
|
| 75 | }
|
| 76 | - Ok(
|
| 77 | + Ok(Some(
|
| 78 | create_systemd_cgroup_manager(root, cgroup_path, config.container_name.as_str())?
|
| 79 | .any(),
|
| 80 | - )
|
| 81 | + ))
|
| 82 | }
|
| 83 | }
|
| 84 | }
|
| 85 |
|
| 86 | pub fn create_cgroup_manager(
|
| 87 | config: CgroupConfig,
|
| 88 | -) -> Result<AnyCgroupManager, CreateCgroupSetupError> {
|
| 89 | +) -> Result<Option<AnyCgroupManager>, CreateCgroupSetupError> {
|
| 90 | create_cgroup_manager_with_root(Some(Path::new(DEFAULT_CGROUP_ROOT)), config)
|
| 91 | }
|
| 92 |
|
| 93 | diff --git a/crates/libcontainer/src/container/builder_impl.rs b/crates/libcontainer/src/container/builder_impl.rs
|
| 94 | index 8d8494bd76..96f098ad33 100644
|
| 95 | |
| 96 | |
| 97 | @@ -88,7 +88,8 @@ impl ContainerBuilderImpl {
|
| 98 | let cgroups_path = utils::get_cgroup_path(linux.cgroups_path(), &self.container_id);
|
| 99 | let cgroup_config = libcgroups::common::CgroupConfig {
|
| 100 | cgroup_path: cgroups_path,
|
| 101 | - systemd_cgroup: self.use_systemd || self.user_ns_config.is_some(),
|
| 102 | + systemd_cgroup: self.use_systemd,
|
| 103 | + rootless_container: self.user_ns_config.is_some(),
|
| 104 | container_name: self.container_id.to_owned(),
|
| 105 | };
|
| 106 | let process = self
|
| 107 | @@ -212,15 +213,18 @@ impl ContainerBuilderImpl {
|
| 108 | let cmanager =
|
| 109 | libcgroups::common::create_cgroup_manager(libcgroups::common::CgroupConfig {
|
| 110 | cgroup_path: cgroups_path,
|
| 111 | - systemd_cgroup: self.use_systemd || self.user_ns_config.is_some(),
|
| 112 | + systemd_cgroup: self.use_systemd,
|
| 113 | + rootless_container: self.user_ns_config.is_some(),
|
| 114 | container_name: self.container_id.to_string(),
|
| 115 | })?;
|
| 116 |
|
| 117 | let mut errors = Vec::new();
|
| 118 |
|
| 119 | - if let Err(e) = cmanager.remove() {
|
| 120 | - tracing::error!(error = ?e, "failed to remove cgroup manager");
|
| 121 | - errors.push(e.to_string());
|
| 122 | + if let Some(cmanager) = cmanager {
|
| 123 | + if let Err(e) = cmanager.remove() {
|
| 124 | + tracing::error!(error = ?e, "failed to remove cgroup manager");
|
| 125 | + errors.push(e.to_string());
|
| 126 | + }
|
| 127 | }
|
| 128 |
|
| 129 | if let Some(container) = &self.container {
|
| 130 | diff --git a/crates/libcontainer/src/container/container.rs b/crates/libcontainer/src/container/container.rs
|
| 131 | index 7a05c3495f..2abe190cc1 100644
|
| 132 | |
| 133 | |
| 134 | @@ -130,6 +130,15 @@ impl Container {
|
| 135 | self
|
| 136 | }
|
| 137 |
|
| 138 | + pub fn rootless(&self) -> bool {
|
| 139 | + self.state.is_rootless
|
| 140 | + }
|
| 141 | +
|
| 142 | + pub fn set_rootless(&mut self, is_rootless: bool) -> &mut Self {
|
| 143 | + self.state.is_rootless = is_rootless;
|
| 144 | + self
|
| 145 | + }
|
| 146 | +
|
| 147 | pub fn set_clean_up_intel_rdt_directory(&mut self, clean_up: bool) -> &mut Self {
|
| 148 | self.state.clean_up_intel_rdt_subdirectory = Some(clean_up);
|
| 149 | self
|
| 150 | diff --git a/crates/libcontainer/src/container/container_delete.rs b/crates/libcontainer/src/container/container_delete.rs
|
| 151 | index d246658c32..69aea6f537 100644
|
| 152 | |
| 153 | |
| 154 | @@ -89,13 +89,16 @@ impl Container {
|
| 155 | libcgroups::common::CgroupConfig {
|
| 156 | cgroup_path: config.cgroup_path.to_owned(),
|
| 157 | systemd_cgroup: self.systemd(),
|
| 158 | + rootless_container: self.rootless(),
|
| 159 | container_name: self.id().to_string(),
|
| 160 | },
|
| 161 | )?;
|
| 162 | - cmanager.remove().map_err(|err| {
|
| 163 | + if let Some(cmanager) = cmanager {
|
| 164 | + cmanager.remove().map_err(|err| {
|
| 165 | tracing::error!(cgroup_path = ?config.cgroup_path, "failed to remove cgroup due to: {err:?}");
|
| 166 | err
|
| 167 | })?;
|
| 168 | + }
|
| 169 |
|
| 170 | if let Some(hooks) = config.hooks.as_ref() {
|
| 171 | hooks::run_hooks(hooks.poststop().as_ref(), Some(self), None).map_err(
|
| 172 | diff --git a/crates/libcontainer/src/container/container_events.rs b/crates/libcontainer/src/container/container_events.rs
|
| 173 | index 83df282f4d..8ee0455356 100644
|
| 174 | |
| 175 | |
| 176 | @@ -38,26 +38,29 @@ impl Container {
|
| 177 | libcgroups::common::create_cgroup_manager(libcgroups::common::CgroupConfig {
|
| 178 | cgroup_path: self.spec()?.cgroup_path,
|
| 179 | systemd_cgroup: self.systemd(),
|
| 180 | + rootless_container: self.rootless(),
|
| 181 | container_name: self.id().to_string(),
|
| 182 | })?;
|
| 183 | - match stats {
|
| 184 | - true => {
|
| 185 | - let stats = cgroup_manager.stats()?;
|
| 186 | - println!(
|
| 187 | - "{}",
|
| 188 | - serde_json::to_string_pretty(&stats)
|
| 189 | - .map_err(LibcontainerError::OtherSerialization)?
|
| 190 | - );
|
| 191 | + if let Some(cgroup_manager) = cgroup_manager {
|
| 192 | + match stats {
|
| 193 | + true => {
|
| 194 | + let stats = cgroup_manager.stats()?;
|
| 195 | + println!(
|
| 196 | + "{}",
|
| 197 | + serde_json::to_string_pretty(&stats)
|
| 198 | + .map_err(LibcontainerError::OtherSerialization)?
|
| 199 | + );
|
| 200 | + }
|
| 201 | + false => loop {
|
| 202 | + let stats = cgroup_manager.stats()?;
|
| 203 | + println!(
|
| 204 | + "{}",
|
| 205 | + serde_json::to_string_pretty(&stats)
|
| 206 | + .map_err(LibcontainerError::OtherSerialization)?
|
| 207 | + );
|
| 208 | + thread::sleep(Duration::from_secs(interval as u64));
|
| 209 | + },
|
| 210 | }
|
| 211 | - false => loop {
|
| 212 | - let stats = cgroup_manager.stats()?;
|
| 213 | - println!(
|
| 214 | - "{}",
|
| 215 | - serde_json::to_string_pretty(&stats)
|
| 216 | - .map_err(LibcontainerError::OtherSerialization)?
|
| 217 | - );
|
| 218 | - thread::sleep(Duration::from_secs(interval as u64));
|
| 219 | - },
|
| 220 | }
|
| 221 |
|
| 222 | Ok(())
|
| 223 | diff --git a/crates/libcontainer/src/container/container_kill.rs b/crates/libcontainer/src/container/container_kill.rs
|
| 224 | index fc5da3db9e..53faa74e6a 100644
|
| 225 | |
| 226 | |
| 227 | @@ -86,10 +86,13 @@ impl Container {
|
| 228 | libcgroups::common::CgroupConfig {
|
| 229 | cgroup_path: self.spec()?.cgroup_path,
|
| 230 | systemd_cgroup: self.systemd(),
|
| 231 | + rootless_container: self.rootless(),
|
| 232 | container_name: self.id().to_string(),
|
| 233 | },
|
| 234 | )?;
|
| 235 | - cmanager.freeze(libcgroups::common::FreezerState::Thawed)?;
|
| 236 | + if let Some(cmanager) = cmanager {
|
| 237 | + cmanager.freeze(libcgroups::common::FreezerState::Thawed)?;
|
| 238 | + }
|
| 239 | }
|
| 240 | libcgroups::common::CgroupSetup::Unified => {}
|
| 241 | }
|
| 242 | @@ -103,37 +106,40 @@ impl Container {
|
| 243 | libcgroups::common::create_cgroup_manager(libcgroups::common::CgroupConfig {
|
| 244 | cgroup_path: self.spec()?.cgroup_path,
|
| 245 | systemd_cgroup: self.systemd(),
|
| 246 | + rootless_container: self.rootless(),
|
| 247 | container_name: self.id().to_string(),
|
| 248 | })?;
|
| 249 |
|
| 250 | - if let Err(e) = cmanager.freeze(libcgroups::common::FreezerState::Frozen) {
|
| 251 | - tracing::warn!(
|
| 252 | - err = ?e,
|
| 253 | - id = ?self.id(),
|
| 254 | - "failed to freeze container",
|
| 255 | - );
|
| 256 | - }
|
| 257 | + if let Some(cmanager) = cmanager {
|
| 258 | + if let Err(e) = cmanager.freeze(libcgroups::common::FreezerState::Frozen) {
|
| 259 | + tracing::warn!(
|
| 260 | + err = ?e,
|
| 261 | + id = ?self.id(),
|
| 262 | + "failed to freeze container",
|
| 263 | + );
|
| 264 | + }
|
| 265 |
|
| 266 | - let pids = cmanager.get_all_pids()?;
|
| 267 | - pids.iter()
|
| 268 | - .try_for_each(|&pid| {
|
| 269 | - tracing::debug!("kill signal {} to {}", signal, pid);
|
| 270 | - let res = signal::kill(pid, signal);
|
| 271 | - match res {
|
| 272 | - Err(nix::errno::Errno::ESRCH) => {
|
| 273 | - // the process does not exist, which is what we want
|
| 274 | - Ok(())
|
| 275 | + let pids = cmanager.get_all_pids()?;
|
| 276 | + pids.iter()
|
| 277 | + .try_for_each(|&pid| {
|
| 278 | + tracing::debug!("kill signal {} to {}", signal, pid);
|
| 279 | + let res = signal::kill(pid, signal);
|
| 280 | + match res {
|
| 281 | + Err(nix::errno::Errno::ESRCH) => {
|
| 282 | + // the process does not exist, which is what we want
|
| 283 | + Ok(())
|
| 284 | + }
|
| 285 | + _ => res,
|
| 286 | }
|
| 287 | - _ => res,
|
| 288 | - }
|
| 289 | - })
|
| 290 | - .map_err(LibcontainerError::OtherSyscall)?;
|
| 291 | - if let Err(err) = cmanager.freeze(libcgroups::common::FreezerState::Thawed) {
|
| 292 | - tracing::warn!(
|
| 293 | - err = ?err,
|
| 294 | - id = ?self.id(),
|
| 295 | - "failed to thaw container",
|
| 296 | - );
|
| 297 | + })
|
| 298 | + .map_err(LibcontainerError::OtherSyscall)?;
|
| 299 | + if let Err(err) = cmanager.freeze(libcgroups::common::FreezerState::Thawed) {
|
| 300 | + tracing::warn!(
|
| 301 | + err = ?err,
|
| 302 | + id = ?self.id(),
|
| 303 | + "failed to thaw container",
|
| 304 | + );
|
| 305 | + }
|
| 306 | }
|
| 307 |
|
| 308 | Ok(())
|
| 309 | diff --git a/crates/libcontainer/src/container/container_pause.rs b/crates/libcontainer/src/container/container_pause.rs
|
| 310 | index 7dcfa77936..50776e6b8d 100644
|
| 311 | |
| 312 | |
| 313 | @@ -36,9 +36,12 @@ impl Container {
|
| 314 | libcgroups::common::create_cgroup_manager(libcgroups::common::CgroupConfig {
|
| 315 | cgroup_path: self.spec()?.cgroup_path,
|
| 316 | systemd_cgroup: self.systemd(),
|
| 317 | + rootless_container: self.rootless(),
|
| 318 | container_name: self.id().to_string(),
|
| 319 | })?;
|
| 320 | - cmanager.freeze(FreezerState::Frozen)?;
|
| 321 | + if let Some(cmanager) = cmanager {
|
| 322 | + cmanager.freeze(FreezerState::Frozen)?;
|
| 323 | + }
|
| 324 |
|
| 325 | tracing::debug!("saving paused status");
|
| 326 | self.set_status(ContainerStatus::Paused).save()?;
|
| 327 | diff --git a/crates/libcontainer/src/container/container_resume.rs b/crates/libcontainer/src/container/container_resume.rs
|
| 328 | index 48fd65d849..0310c58109 100644
|
| 329 | |
| 330 | |
| 331 | @@ -37,10 +37,13 @@ impl Container {
|
| 332 | libcgroups::common::create_cgroup_manager(libcgroups::common::CgroupConfig {
|
| 333 | cgroup_path: self.spec()?.cgroup_path,
|
| 334 | systemd_cgroup: self.systemd(),
|
| 335 | + rootless_container: self.rootless(),
|
| 336 | container_name: self.id().to_string(),
|
| 337 | })?;
|
| 338 | // resume the frozen container
|
| 339 | - cmanager.freeze(FreezerState::Thawed)?;
|
| 340 | + if let Some(cmanager) = cmanager {
|
| 341 | + cmanager.freeze(FreezerState::Thawed)?;
|
| 342 | + }
|
| 343 |
|
| 344 | tracing::debug!("saving running status");
|
| 345 | self.set_status(ContainerStatus::Running).save()?;
|
| 346 | diff --git a/crates/libcontainer/src/container/init_builder.rs b/crates/libcontainer/src/container/init_builder.rs
|
| 347 | index 86e728802d..64b7e741ad 100644
|
| 348 | |
| 349 | |
| 350 | @@ -89,6 +89,7 @@ impl InitContainerBuilder {
|
| 351 | };
|
| 352 |
|
| 353 | let user_ns_config = UserNamespaceConfig::new(&spec)?;
|
| 354 | + container.set_rootless(user_ns_config.is_some());
|
| 355 |
|
| 356 | let config = YoukiConfig::from_spec(&spec, container.id())?;
|
| 357 | config.save(&container_dir).map_err(|err| {
|
| 358 | diff --git a/crates/libcontainer/src/container/state.rs b/crates/libcontainer/src/container/state.rs
|
| 359 | index 4f0bc07aac..068f92920d 100644
|
| 360 | |
| 361 | |
| 362 | @@ -114,6 +114,8 @@ pub struct State {
|
| 363 | pub creator: Option<u32>,
|
| 364 | // Specifies if systemd should be used to manage cgroups
|
| 365 | pub use_systemd: bool,
|
| 366 | + // Specifies if the container is rootless.
|
| 367 | + pub is_rootless: bool,
|
| 368 | // Specifies if the Intel RDT subdirectory needs be cleaned up.
|
| 369 | pub clean_up_intel_rdt_subdirectory: Option<bool>,
|
| 370 | }
|
| 371 | @@ -137,6 +139,7 @@ impl State {
|
| 372 | created: None,
|
| 373 | creator: None,
|
| 374 | use_systemd: false,
|
| 375 | + is_rootless: false,
|
| 376 | clean_up_intel_rdt_subdirectory: None,
|
| 377 | }
|
| 378 | }
|
| 379 | diff --git a/crates/libcontainer/src/process/container_intermediate_process.rs b/crates/libcontainer/src/process/container_intermediate_process.rs
|
| 380 | index 1bee6f3eee..a2c3310f2a 100644
|
| 381 | |
| 382 | |
| 383 | @@ -62,11 +62,13 @@ pub fn container_intermediate_process(
|
| 384 | // In addition this needs to be done before we enter the cgroup namespace as
|
| 385 | // the cgroup of the process will form the root of the cgroup hierarchy in
|
| 386 | // the cgroup namespace.
|
| 387 | - apply_cgroups(
|
| 388 | - &cgroup_manager,
|
| 389 | - linux.resources().as_ref(),
|
| 390 | - matches!(args.container_type, ContainerType::InitContainer),
|
| 391 | - )?;
|
| 392 | + if let Some(cgroup_manager) = cgroup_manager {
|
| 393 | + apply_cgroups(
|
| 394 | + &cgroup_manager,
|
| 395 | + linux.resources().as_ref(),
|
| 396 | + matches!(args.container_type, ContainerType::InitContainer),
|
| 397 | + )?;
|
| 398 | + }
|
| 399 |
|
| 400 | // if new user is specified in specification, this will be true and new
|
| 401 | // namespace will be created, check
|
| 402 | diff --git a/crates/youki/src/commands/mod.rs b/crates/youki/src/commands/mod.rs
|
| 403 | index 08044b7fbf..d7e84df147 100644
|
| 404 | |
| 405 | |
| 406 | @@ -55,12 +55,13 @@ fn container_exists<P: AsRef<Path>>(root_path: P, container_id: &str) -> Result<
|
| 407 | fn create_cgroup_manager<P: AsRef<Path>>(
|
| 408 | root_path: P,
|
| 409 | container_id: &str,
|
| 410 | -) -> Result<AnyCgroupManager> {
|
| 411 | +) -> Result<Option<AnyCgroupManager>> {
|
| 412 | let container = load_container(root_path, container_id)?;
|
| 413 | Ok(libcgroups::common::create_cgroup_manager(
|
| 414 | libcgroups::common::CgroupConfig {
|
| 415 | cgroup_path: container.spec()?.cgroup_path,
|
| 416 | systemd_cgroup: container.systemd(),
|
| 417 | + rootless_container: container.rootless(),
|
| 418 | container_name: container.id().to_string(),
|
| 419 | },
|
| 420 | )?)
|
| 421 | diff --git a/crates/youki/src/commands/ps.rs b/crates/youki/src/commands/ps.rs
|
| 422 | index a195196ac9..4cf2d09040 100644
|
| 423 | |
| 424 | |
| 425 | @@ -10,37 +10,39 @@ use crate::commands::create_cgroup_manager;
|
| 426 | pub fn ps(args: Ps, root_path: PathBuf) -> Result<()> {
|
| 427 | let cmanager = create_cgroup_manager(root_path, &args.container_id)?;
|
| 428 |
|
| 429 | - let pids: Vec<i32> = cmanager
|
| 430 | - .get_all_pids()?
|
| 431 | - .iter()
|
| 432 | - .map(|pid| pid.as_raw())
|
| 433 | - .collect();
|
| 434 | + if let Some(cmanager) = cmanager {
|
| 435 | + let pids: Vec<i32> = cmanager
|
| 436 | + .get_all_pids()?
|
| 437 | + .iter()
|
| 438 | + .map(|pid| pid.as_raw())
|
| 439 | + .collect();
|
| 440 |
|
| 441 | - if args.format == "json" {
|
| 442 | - println!("{}", serde_json::to_string(&pids)?);
|
| 443 | - } else if args.format == "table" {
|
| 444 | - let default_ps_options = vec![String::from("-ef")];
|
| 445 | - let ps_options = if args.ps_options.is_empty() {
|
| 446 | - &default_ps_options
|
| 447 | - } else {
|
| 448 | - &args.ps_options
|
| 449 | - };
|
| 450 | - let output = Command::new("ps").args(ps_options).output()?;
|
| 451 | - if !output.status.success() {
|
| 452 | - println!("{}", std::str::from_utf8(&output.stderr)?);
|
| 453 | - } else {
|
| 454 | - let lines = std::str::from_utf8(&output.stdout)?;
|
| 455 | - let lines: Vec<&str> = lines.split('\n').collect();
|
| 456 | - let pid_index = get_pid_index(lines[0])?;
|
| 457 | - println!("{}", &lines[0]);
|
| 458 | - for line in &lines[1..] {
|
| 459 | - if line.is_empty() {
|
| 460 | - continue;
|
| 461 | - }
|
| 462 | - let fields: Vec<&str> = line.split_whitespace().collect();
|
| 463 | - let pid: i32 = fields[pid_index].parse()?;
|
| 464 | - if pids.contains(&pid) {
|
| 465 | - println!("{line}");
|
| 466 | + if args.format == "json" {
|
| 467 | + println!("{}", serde_json::to_string(&pids)?);
|
| 468 | + } else if args.format == "table" {
|
| 469 | + let default_ps_options = vec![String::from("-ef")];
|
| 470 | + let ps_options = if args.ps_options.is_empty() {
|
| 471 | + &default_ps_options
|
| 472 | + } else {
|
| 473 | + &args.ps_options
|
| 474 | + };
|
| 475 | + let output = Command::new("ps").args(ps_options).output()?;
|
| 476 | + if !output.status.success() {
|
| 477 | + println!("{}", std::str::from_utf8(&output.stderr)?);
|
| 478 | + } else {
|
| 479 | + let lines = std::str::from_utf8(&output.stdout)?;
|
| 480 | + let lines: Vec<&str> = lines.split('\n').collect();
|
| 481 | + let pid_index = get_pid_index(lines[0])?;
|
| 482 | + println!("{}", &lines[0]);
|
| 483 | + for line in &lines[1..] {
|
| 484 | + if line.is_empty() {
|
| 485 | + continue;
|
| 486 | + }
|
| 487 | + let fields: Vec<&str> = line.split_whitespace().collect();
|
| 488 | + let pid: i32 = fields[pid_index].parse()?;
|
| 489 | + if pids.contains(&pid) {
|
| 490 | + println!("{line}");
|
| 491 | + }
|
| 492 | }
|
| 493 | }
|
| 494 | }
|
| 495 | diff --git a/crates/youki/src/commands/update.rs b/crates/youki/src/commands/update.rs
|
| 496 | index 115c334274..d43e9fd05c 100644
|
| 497 | |
| 498 | |
| 499 | @@ -12,28 +12,30 @@ use crate::commands::create_cgroup_manager;
|
| 500 | pub fn update(args: Update, root_path: PathBuf) -> Result<()> {
|
| 501 | let cmanager = create_cgroup_manager(root_path, &args.container_id)?;
|
| 502 |
|
| 503 | - let linux_res: LinuxResources;
|
| 504 | - if let Some(resources_path) = args.resources {
|
| 505 | - linux_res = if resources_path.to_string_lossy() == "-" {
|
| 506 | - serde_json::from_reader(io::stdin())?
|
| 507 | + if let Some(cmanager) = cmanager {
|
| 508 | + let linux_res: LinuxResources;
|
| 509 | + if let Some(resources_path) = args.resources {
|
| 510 | + linux_res = if resources_path.to_string_lossy() == "-" {
|
| 511 | + serde_json::from_reader(io::stdin())?
|
| 512 | + } else {
|
| 513 | + let file = fs::File::open(resources_path)?;
|
| 514 | + let reader = io::BufReader::new(file);
|
| 515 | + serde_json::from_reader(reader)?
|
| 516 | + };
|
| 517 | } else {
|
| 518 | - let file = fs::File::open(resources_path)?;
|
| 519 | - let reader = io::BufReader::new(file);
|
| 520 | - serde_json::from_reader(reader)?
|
| 521 | - };
|
| 522 | - } else {
|
| 523 | - let mut builder = LinuxResourcesBuilder::default();
|
| 524 | - if let Some(new_pids_limit) = args.pids_limit {
|
| 525 | - builder = builder.pids(LinuxPidsBuilder::default().limit(new_pids_limit).build()?);
|
| 526 | + let mut builder = LinuxResourcesBuilder::default();
|
| 527 | + if let Some(new_pids_limit) = args.pids_limit {
|
| 528 | + builder = builder.pids(LinuxPidsBuilder::default().limit(new_pids_limit).build()?);
|
| 529 | + }
|
| 530 | + linux_res = builder.build()?;
|
| 531 | }
|
| 532 | - linux_res = builder.build()?;
|
| 533 | - }
|
| 534 |
|
| 535 | - cmanager.apply(&ControllerOpt {
|
| 536 | - resources: &linux_res,
|
| 537 | - disable_oom_killer: false,
|
| 538 | - oom_score_adj: None,
|
| 539 | - freezer_state: None,
|
| 540 | - })?;
|
| 541 | + cmanager.apply(&ControllerOpt {
|
| 542 | + resources: &linux_res,
|
| 543 | + disable_oom_killer: false,
|
| 544 | + oom_score_adj: None,
|
| 545 | + freezer_state: None,
|
| 546 | + })?;
|
| 547 | + }
|
| 548 | Ok(())
|
| 549 | }
|