kanit

Toy init system
Log | Files | Refs | README | LICENSE

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 }