From d66c2bcf45da7b603b72d605352989f6f630be00 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Mon, 10 Mar 2025 22:16:32 +0100 Subject: [PATCH] WIP: choom --- Cargo.lock | 10 ++++ Cargo.toml | 2 + src/uu/choom/Cargo.toml | 16 +++++++ src/uu/choom/choom.md | 9 ++++ src/uu/choom/src/choom.rs | 97 +++++++++++++++++++++++++++++++++++++++ src/uu/choom/src/main.rs | 1 + 6 files changed, 135 insertions(+) create mode 100644 src/uu/choom/Cargo.toml create mode 100644 src/uu/choom/choom.md create mode 100644 src/uu/choom/src/choom.rs create mode 100644 src/uu/choom/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index f377304..987505f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -969,6 +969,7 @@ dependencies = [ "tempfile", "textwrap", "uu_blockdev", + "uu_choom", "uu_ctrlaltdel", "uu_dmesg", "uu_fsfreeze", @@ -994,6 +995,15 @@ dependencies = [ "uucore", ] +[[package]] +name = "uu_choom" +version = "0.0.1" +dependencies = [ + "clap", + "linux-raw-sys 0.9.2", + "uucore", +] + [[package]] name = "uu_ctrlaltdel" version = "0.0.1" diff --git a/Cargo.toml b/Cargo.toml index 2c7adc1..3c02268 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ uudoc = [] feat_common_core = [ "blockdev", + "choom", "ctrlaltdel", "dmesg", "fsfreeze", @@ -72,6 +73,7 @@ uucore = { workspace = true } # blockdev = { optional = true, version = "0.0.1", package = "uu_blockdev", path = "src/uu/blockdev" } +choom = { optional = true, version = "0.0.1", package = "uu_choom", path = "src/uu/choom" } ctrlaltdel = { optional = true, version = "0.0.1", package = "uu_ctrlaltdel", path = "src/uu/ctrlaltdel" } dmesg = { optional = true, version = "0.0.1", package = "uu_dmesg", path = "src/uu/dmesg" } fsfreeze = { optional = true, version = "0.0.1", package = "uu_fsfreeze", path = "src/uu/fsfreeze" } diff --git a/src/uu/choom/Cargo.toml b/src/uu/choom/Cargo.toml new file mode 100644 index 0000000..da182fe --- /dev/null +++ b/src/uu/choom/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "uu_choom" +version = "0.0.1" +edition = "2021" + +[lib] +path = "src/choom.rs" + +[[bin]] +name = "choom" +path = "src/main.rs" + +[dependencies] +clap = { workspace = true } +linux-raw-sys = { workspace = true } +uucore = { workspace = true } diff --git a/src/uu/choom/choom.md b/src/uu/choom/choom.md new file mode 100644 index 0000000..96a8dec --- /dev/null +++ b/src/uu/choom/choom.md @@ -0,0 +1,9 @@ +# choom + +``` +choom [OPTION] -p pid +choom [OPTION] -n number -p pid +choom [OPTION] -n number [--] command [args...]] +``` + +Display and adjust OOM-killer score. diff --git a/src/uu/choom/src/choom.rs b/src/uu/choom/src/choom.rs new file mode 100644 index 0000000..c287cd0 --- /dev/null +++ b/src/uu/choom/src/choom.rs @@ -0,0 +1,97 @@ +// This file is part of the uutils util-linux package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +use clap::{crate_version, Arg, ArgAction, ArgGroup, Command}; +use std::io::Write; +use uucore::{error::UResult, format_usage, help_about, help_usage}; + +const ABOUT: &str = help_about!("choom.md"); +const USAGE: &str = help_usage!("choom.md"); + +mod options { + pub const PID: &str = "pid"; + pub const ADJUST: &str = "adjust"; +} + +#[cfg(target_os = "linux")] +#[uucore::main] +pub fn uumain(args: impl uucore::Args) -> UResult<()> { + let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?; + if let Some(adjust) = matches.get_one::(options::ADJUST) { + let pid = match matches.get_one::(options::PID) { + Some(pid) => *pid, + None => std::process::id(), + }; + adjust_oom_score(pid, *adjust)?; + } else if let Some(pid) = matches.get_one::(options::PID) { + print_oom_score(*pid)?; + } + + Ok(()) +} + +pub fn adjust_oom_score(pid: u32, adjust: i32) -> UResult<()> { + let path = format!("/proc/{}/oom_score_adj", pid); + let mut file = std::fs::OpenOptions::new().write(true).open(path)?; + file.write_all(adjust.to_string().as_bytes())?; + Ok(()) +} + +pub fn print_oom_score(pid: u32) -> UResult<()> { + let path = format!("/proc/{}/oom_score", pid); + let score = std::fs::read_to_string(path)?; + println!("pid {}'s current OOM score: {}", pid, score.trim()); + let path = format!("/proc/{}/oom_score_adj", pid); + let score = std::fs::read_to_string(path)?; + println!( + "pid {}'s current OOM score adjust value: {}", + pid, + score.trim() + ); + Ok(()) +} + +pub fn uu_app() -> Command { + Command::new(uucore::util_name()) + .version(crate_version!()) + .about(ABOUT) + .override_usage(format_usage(USAGE)) + .infer_long_args(true) + .arg( + Arg::new(options::ADJUST) + .short('n') + .long(options::ADJUST) + .help("specify the adjust score value") + .action(ArgAction::Set) + .value_name("num") + .value_parser(clap::value_parser!(i32)), + ) + .arg( + Arg::new(options::PID) + .short('p') + .long(options::PID) + .help("process ID") + .action(ArgAction::Set) + .value_name("num") + .value_parser(clap::value_parser!(u32)), + ) + .group( + ArgGroup::new("action") + .args([options::ADJUST, options::PID]) + .required(true) + .multiple(true), + ) +} + +#[cfg(not(target_os = "linux"))] +#[uucore::main] +pub fn uumain(args: impl uucore::Args) -> UResult<()> { + let _matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?; + + Err(uucore::error::USimpleError::new( + 1, + "`choom` is available only on Linux.", + )) +} diff --git a/src/uu/choom/src/main.rs b/src/uu/choom/src/main.rs new file mode 100644 index 0000000..bb2033c --- /dev/null +++ b/src/uu/choom/src/main.rs @@ -0,0 +1 @@ +uucore::bin!(uu_choom);