From c5a10ebbf36b8c7543455436c99afdaa08d16e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Corr=C3=AAa?= Date: Sun, 25 Feb 2024 22:41:22 +0000 Subject: [PATCH] (WIP) feat: Add more configurations so it can be used with the steam deck --- Cargo.lock | 15 +++------- Cargo.toml | 2 +- README.md | 20 +++++++++++++ src/commands/enable.rs | 67 ++++++++++++++++++++++++++---------------- src/main.rs | 24 +++++++++++++-- 5 files changed, 88 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index abcb37e..ae8f176 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -167,24 +167,23 @@ checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "cmd_lib" -version = "1.6.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66455dd56c2a82e34679003d080f44cb6c92bebe855f7945b4093c1c36d1c12d" +checksum = "e5f4cbdcab51ca635c5b19c85ece4072ea42e0d2360242826a6fc96fb11f0d40" dependencies = [ "cmd_lib_macros", "env_logger", "faccess", "lazy_static", "log", - "main_error", "os_pipe", ] [[package]] name = "cmd_lib_macros" -version = "1.6.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "548393c11c2d876ebebab81196033ebfe61663702c6c8a176f97df07d4139ed2" +checksum = "ae881960f7e2a409f91ef0b1c09558cf293031a1d6e8b45f908311f2a43f5fdf" dependencies = [ "proc-macro-error", "proc-macro2", @@ -396,12 +395,6 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "main_error" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155db5e86c6e45ee456bf32fad5a290ee1f7151c2faca27ea27097568da67d1a" - [[package]] name = "memchr" version = "2.6.4" diff --git a/Cargo.toml b/Cargo.toml index de9ce17..2d3bc91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] clap = { version = "4.4.7", features = ["derive"] } -cmd_lib = "1.6.0" +cmd_lib = "1.9.3" color-eyre = "0.6.2" envfile = "0.2.1" eyre = "0.6.8" diff --git a/README.md b/README.md index 6e9cabd..dbbc9c9 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,26 @@ cargo build --release sudo ./target/release/hibernation-control enable ``` +## Steam Deck + +You will need a manual step to get it working with the Steam Deck. Add `resume` to `HOOKS` at `/etc/mkinitcpio.conf` + +Then you can execute: + +```sh +sudo ./hibernate-control enable -s /path-to-your-swapfile +``` + +If don't want the new swapfile to be used for swap, you can run: + +_TODO_ set priority +_TODO_ persist swap configuration (fstab or a systemd service) +_TODO_ How do I add it to the menu? + +```sh +sudo ./hibernate-control enable -s /path-to-your-swapfile --swapfile-size 16_000_000 +``` + ## Features - Set up a swapfile of appropriate size (2 time the RAM) diff --git a/src/commands/enable.rs b/src/commands/enable.rs index 7af9313..68d8f29 100644 --- a/src/commands/enable.rs +++ b/src/commands/enable.rs @@ -8,24 +8,36 @@ use sys_info::mem_info; use crate::grub; use crate::systemd; -pub fn run() -> eyre::Result<()> { +pub struct SwapOptions { + pub size: Option, + pub path: Option, +} + +pub struct Options { + pub swap: SwapOptions, +} + +/// Enable hibernation on the system +pub fn run(options: Options) -> eyre::Result<()> { sanity_check()?; run_cmd!(info "Enabling hibernation")?; backup_files()?; - // create_swapfile()?; + let swapfile_path = create_swapfile(&options.swap)?; - let uuid = get_uuid()?; - run_cmd!(info /swapfile uuid=$uuid)?; + let uuid = get_uuid(&swapfile_path)?; + run_cmd!(info ${swapfile_path} uuid=$uuid)?; - let offset = get_offset()?; - run_cmd!(info /swapfile offset=$offset)?; + let offset = get_offset(&swapfile_path)?; + run_cmd!(info ${swapfile_path} offset=$offset)?; set_grub_options(uuid.clone(), offset)?; - set_initramfs_options(uuid, offset)?; - systemd::install()?; + // DONT NEED THESE TWO FOR THE STEAM DECK + // TODO add options to skip them + // set_initramfs_options(uuid, offset)?; + // systemd::install()?; run_cmd!( info Done; @@ -51,8 +63,9 @@ pub fn sanity_check() -> eyre::Result<()> { "swapon", "findmnt", "filefrag", - "grub-mkconfig", - "update-initramfs", + "update-grub", + // "grub-mkconfig", + // "update-initramfs", ] { let test_command = run_fun!(which ${i};); if test_command.is_err() { @@ -74,37 +87,43 @@ pub fn backup_files() -> eyre::Result<()> { Ok(()) } -pub fn create_swapfile() -> eyre::Result<()> { +pub fn create_swapfile(options: &SwapOptions) -> eyre::Result { + let swapfile = options.path.clone().unwrap_or("/swapfile".to_string()); run_cmd!( - info "Creating swapfile (/swapfile)"; - bash -c "swapoff /swapfile || true"; + info "Creating swapfile (${swapfile})"; + bash -c "swapoff ${swapfile} || true"; )?; + let forced_swap_size = options.size.clone(); let memory_size = mem_info()?.total; let swap_size = memory_size * 2; + let swap_size = match forced_swap_size { + Some(size) => size, + None => swap_size, + }; let swap_size_mb = swap_size / 1024; let swap_block_size_mb = 32; let swap_num_blocks = swap_size_mb / swap_block_size_mb; run_cmd!( info "Allocating swapfile (${swap_size}MB)"; - sudo dd if=/dev/zero of=/swapfile bs=${swap_block_size_mb}MB count=${swap_num_blocks}; - chmod 600 /swapfile; - mkswap /swapfile; - swapon /swapfile; + sudo dd if=/dev/zero of=${swapfile} bs=${swap_block_size_mb}MB count=${swap_num_blocks}; + chmod 600 ${swapfile}; + mkswap ${swapfile}; + swapon ${swapfile}; )?; - Ok(()) + Ok(swapfile) } // TODO replace run_fun here -pub fn get_uuid() -> eyre::Result { - let uuid = run_fun!(findmnt -no UUID -T /swapfile)?; +pub fn get_uuid(filepath: &str) -> eyre::Result { + let uuid = run_fun!(findmnt -no UUID -T ${filepath})?; Ok(uuid) } // TODO replace run_fun here -pub fn get_offset() -> eyre::Result { - let first_block = run_fun!(filefrag -v /swapfile | grep " 0:")?; +pub fn get_offset(filepath: &str) -> eyre::Result { + let first_block = run_fun!(filefrag -v ${filepath} | grep " 0:")?; let first_block = first_block.replace(" ", ""); let first_block = first_block.replace("..", ":"); let block_iter = first_block.split(":"); @@ -118,10 +137,8 @@ pub fn set_grub_options(uuid: String, resume_offset: usize) -> eyre::Result<()> grub::set_variable("resume".into(), format!("UUID={uuid}"))?; grub::set_variable("resume_offset".into(), resume_offset.to_string())?; - // TODO use update-grub instead of grub-mkconfig run_cmd!( - grub-mkconfig -o /boot/grub/grub.cfg; - grub-mkconfig -o /boot/efi/EFI/ubuntu/grub.cfg; + update-grub; )?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index 605cf20..274a2f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use clap::{Parser, Subcommand}; +use hibernation_control::commands::enable::{Options, SwapOptions}; /// Manages Hibernation on Linux #[derive(Parser)] @@ -13,7 +14,15 @@ pub struct Cli { enum Commands { /// Create swap file, update fstab and grub, and enable hibernation on systemd #[command()] - Enable, + Enable { + /// Size of the swap file in MiB + #[arg(long)] + swapfile_size: Option, + + /// Path to the swap file + #[arg(short, long)] + swapfile_path: Option, + }, /// This command DOES NOT remove the current swap file #[command()] @@ -23,8 +32,17 @@ enum Commands { fn main() -> eyre::Result<()> { color_eyre::install()?; match Cli::parse().command { - Commands::Enable => { - hibernation_control::commands::enable::run()?; + Commands::Enable { + swapfile_size, + swapfile_path, + } => { + let options = Options { + swap: SwapOptions { + size: swapfile_size, + path: swapfile_path, + }, + }; + hibernation_control::commands::enable::run(options)?; } Commands::Disable => eyre::bail!("TODO"), };