cgroup.rs (1867B)
1 use std::path::Path; 2 3 use async_trait::async_trait; 4 use blocking::unblock; 5 use log::info; 6 use nix::mount::{MsFlags, mount}; 7 use nix::sys::stat::Mode; 8 use nix::unistd::mkdir; 9 10 use kanit_common::error::{Context, ErrorKind, Result, StaticError}; 11 use kanit_unit::{Dependencies, Unit}; 12 13 use crate::mounts::{is_fs_available, try_mount_from_fstab}; 14 use crate::oneshot::SysFs; 15 use crate::unit_name; 16 17 pub struct Cgroup; 18 19 impl Cgroup { 20 // TODO; cgroup1 21 async fn mount_cgroup2() -> Result<()> { 22 if !is_fs_available("cgroup2").await? { 23 Err(StaticError("failed to mount cgroup")).kind(ErrorKind::Unrecoverable)?; 24 }; 25 26 info!("mounting cgroup2"); 27 28 let path = Path::new("/sys/fs/cgroup"); 29 30 if try_mount_from_fstab(path).await? { 31 return Ok(()); 32 } 33 34 unblock(move || { 35 mount( 36 Some("none"), 37 Path::new("/sys/fs/cgroup"), 38 Some("cgroup2"), 39 MsFlags::MS_NODEV | MsFlags::MS_NOSUID | MsFlags::MS_NOEXEC, 40 Some("nsdelegate,memory_recursiveprot"), 41 ) 42 }) 43 .await 44 .context("failed to mount cgroup2")?; 45 46 Ok(()) 47 } 48 49 async fn init_cgroups() -> Result<()> { 50 let path = Path::new("/sys/fs/cgroup"); 51 52 unblock(move || { 53 mkdir( 54 &path.join("system.slice"), 55 Mode::S_IRWXU | Mode::S_IRGRP | Mode::S_IRUSR, 56 ) 57 }) 58 .await 59 .context("failed to create system.slice")?; 60 61 Ok(()) 62 } 63 } 64 65 #[async_trait] 66 impl Unit for Cgroup { 67 unit_name!("cgroup"); 68 69 fn dependencies(&self) -> Dependencies { 70 Dependencies::new().need(SysFs.name()).clone() 71 } 72 73 async fn start(&mut self) -> Result<()> { 74 Self::mount_cgroup2().await?; 75 Self::init_cgroups().await 76 } 77 }