use clap::Parser; use crate::nix::{SchedPolicy, SchedType}; #[derive(Parser, Debug)] pub struct Args { /// Log to STDERR in addition to journald #[arg(long)] pub stderr: bool, /// Run daemon as user #[arg(long, default_value = "rtkit", value_name = "USER")] pub user_name: String, /// Choose scheduling policy #[arg(long, default_value_t = SchedulingPolicy::Rr)] pub scheduling_policy: SchedulingPolicy, /// Realtime priority for the daemon #[arg(long, default_value = "0", value_name = "[0..99]")] pub our_realtime_priority: u32, /// Nice level for the daemon #[arg(long, default_value = "0", value_name = "[-20..19]")] pub our_nice_level: i32, /// Max realtime priority for clients #[arg(long, default_value = "99", value_name = "[0..99]")] pub max_realtime_priority: u32, /// Min nice level for clients #[arg(long, default_value = "-20", value_name = "[-20..19]")] pub min_nice_level: i32, /// Require clients to have set RLIMIT_RTTIME not greater than this #[arg(long, value_name = "USEC")] pub rttime_usec_max: Option, /// How many users this daemon will serve at max at the same time #[arg(long)] pub users_max: Option, /// How many processes this daemon will serve at max per user at the same time #[arg(long)] pub processes_per_user_max: Option, /// How many threads this daemon will serve at max per user at the same time #[arg(long)] pub threads_per_user_max: Option, /// Enforce requests limits in this time #[arg(long, value_name = "SEC")] pub actions_burst_sec: Option, /// Allow this many requests per burst #[arg(long)] pub actions_per_burst_max: Option, /// Canary cheep interval #[arg(long, default_value = "5000", value_name = "MILLISEC")] pub canary_cheep_msec: u32, /// Watchdog action delay #[arg(long, default_value = "10000", value_name = "MILLISEC")] pub canary_watchdog_msec: u32, /// When the canary dies demote unknown processes too? #[arg(long)] pub canary_demote_unknown: bool, /// When the canary dies demote root processes too? #[arg(long)] pub canary_demote_root: bool, /// How long to refuse further requests after the canary died #[arg(long, default_value = "300", value_name = "SEC")] pub canary_refuse_sec: u32, /// Don't run a canary-based RT watchdog #[arg(long)] pub no_canary: bool, /// Don't drop privileges #[arg(long)] pub no_drop_privileges: bool, /// Don't chroot #[arg(long)] pub no_chroot: bool, /// Don't limit daemon's resources #[arg(long)] pub no_limit_resources: bool, } impl Args { pub fn proc_dir(&self) -> &str { if self.no_chroot { "/proc" } else { "/" } } pub fn scheduling_policy(&self) -> SchedPolicy { let sched_type: SchedType = self.scheduling_policy.into(); SchedPolicy::new(sched_type) } } #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum SchedulingPolicy { Fifo, Rr, } impl std::str::FromStr for SchedulingPolicy { type Err = String; fn from_str(s: &str) -> Result { match s { "FIFO" | "fifo" => Ok(Self::Fifo), "RR" | "rr" => Ok(Self::Rr), _ => Err(format!("unknown scheduling policy: {}", s)), } } } impl std::fmt::Display for SchedulingPolicy { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::Fifo => write!(f, "FIFO"), Self::Rr => write!(f, "RR"), } } } impl Into for SchedulingPolicy { fn into(self) -> SchedType { match self { Self::Fifo => SchedType::SCHED_FIFO, Self::Rr => SchedType::SCHED_RR, } } }