136 lines
3.1 KiB
Rust
136 lines
3.1 KiB
Rust
use nix::unistd::{Pid, Uid};
|
|
|
|
use anyhow::Result;
|
|
|
|
use crate::{
|
|
cli::Args, nix::{sched_get_priority_max, sched_get_priority_min}, self_drop_realtime, self_set_realtime
|
|
};
|
|
|
|
struct User {
|
|
uid: Uid,
|
|
timestamp: u64,
|
|
n_actions: u32,
|
|
processes: Vec<Process>,
|
|
}
|
|
|
|
struct Process {
|
|
pid: Pid,
|
|
starttime: u64,
|
|
threads: Vec<Thread>,
|
|
}
|
|
|
|
struct Thread {
|
|
tid: Pid,
|
|
starttime: u64,
|
|
}
|
|
|
|
struct State {
|
|
// TODO:
|
|
}
|
|
|
|
impl State {
|
|
fn make_thread_realtime_with_pid(
|
|
&mut self,
|
|
args: &Args,
|
|
user: User,
|
|
pid: Pid,
|
|
tid: Pid,
|
|
priority: u32,
|
|
) {
|
|
if sched_get_priority_min(args.scheduling_policy())
|
|
.is_ok_and(|min| priority < u32::try_from(min).unwrap())
|
|
|| sched_get_priority_max(args.scheduling_policy())
|
|
.is_ok_and(|max| priority > u32::try_from(max).unwrap())
|
|
{
|
|
todo!("bail EINVAL")
|
|
}
|
|
|
|
// We always want to be able to get a higher RT priority than the client
|
|
if priority >= args.our_realtime_priority
|
|
|| priority > args.max_realtime_priority
|
|
{
|
|
todo!("bail EPERM")
|
|
}
|
|
|
|
// Make sure users don't flood us with requests
|
|
if !verify_burst(&user) {
|
|
todo!("bail EBUSY")
|
|
}
|
|
|
|
// TODO: implement
|
|
|
|
self_drop_realtime(args.our_nice_level);
|
|
}
|
|
|
|
fn make_thread_high_priority_with_pid(&mut self) {
|
|
unimplemented!()
|
|
}
|
|
|
|
fn reset_known(&mut self) {
|
|
unimplemented!()
|
|
}
|
|
|
|
fn reset_all(&mut self) {
|
|
unimplemented!()
|
|
}
|
|
|
|
fn exit(&mut self) {
|
|
unimplemented!()
|
|
}
|
|
}
|
|
|
|
// Polkit
|
|
|
|
// Unix process lookup
|
|
|
|
fn read_start_time(pid: Pid, tid: Pid) -> u64 {
|
|
unimplemented!("Read /proc and get the start time of the process/thread")
|
|
}
|
|
|
|
fn verify_burst(user: &User) -> bool {
|
|
unimplemented!("Check if the user has issued more than ACTIONS_PER_BURST_MAX in this time")
|
|
}
|
|
|
|
// TODO: make into impls
|
|
|
|
// fn find_user(users: &[User], uid: Uid) -> Option<&User> {
|
|
// unimplemented!("Find the user with the given UID")
|
|
// }
|
|
|
|
// fn find_process(user: &User, pid: Pid) -> Option<&Process> {
|
|
// unimplemented!("Find the process with the given PID")
|
|
// }
|
|
|
|
// fn find_thread(process: &Process, tid: Pid) -> Option<&Thread> {
|
|
// unimplemented!("Find the thread with the given TID")
|
|
// }
|
|
|
|
// fn thread_gc(process: &mut Process) {
|
|
// unimplemented!("Garbage collect threads")
|
|
// }
|
|
|
|
// fn process_gc(user: &mut User) {
|
|
// unimplemented!("Garbage collect processes")
|
|
// }
|
|
|
|
// fn user_gc(users: &mut Vec<User>) {
|
|
// unimplemented!("Garbage collect users")
|
|
// }
|
|
|
|
/* This checks if a thread still matters to us, i.e. if its
|
|
* PID still refers to the same thread and if it is still high
|
|
* priority or real time */
|
|
fn thread_relevant(pid: Pid, tid: Pid) -> bool {
|
|
unimplemented!("Check if the thread is still relevant")
|
|
}
|
|
|
|
/* Verifies that RLIMIT_RTTIME is set for the specified process */
|
|
fn verify_process_rttime(process: &Process) -> Result<()> {
|
|
unimplemented!()
|
|
}
|
|
|
|
// Ensure that the user owns the process
|
|
fn verify_process_user(process: &Process, user: &User) -> Result<()> {
|
|
unimplemented!()
|
|
}
|