diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-04-14 17:06:03 +0200 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-04-14 17:06:03 +0200 |
| commit | 6b5e7b7f67e0d09f37ae4e8cb0d57ab416f1e873 (patch) | |
| tree | 2fd8ca601aca89f99019999d6a3743e3785e0b56 /pkgs | |
| parent | pkgs/tskm/inputs: Auto-add a tag for the current date on file import (diff) | |
| download | nixos-config-6b5e7b7f67e0d09f37ae4e8cb0d57ab416f1e873.zip | |
modules/i3status-rust: Use upstream package
My patches have been merged upstream.
Diffstat (limited to 'pkgs')
| -rw-r--r-- | pkgs/by-name/i3/i3status-rust-patched/package.nix | 22 | ||||
| -rw-r--r-- | pkgs/by-name/i3/i3status-rust-patched/patches/0001-disk_space-Support-btrfs-backend.patch | 190 |
2 files changed, 0 insertions, 212 deletions
diff --git a/pkgs/by-name/i3/i3status-rust-patched/package.nix b/pkgs/by-name/i3/i3status-rust-patched/package.nix deleted file mode 100644 index a103e275..00000000 --- a/pkgs/by-name/i3/i3status-rust-patched/package.nix +++ /dev/null @@ -1,22 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - i3status-rust, -}: -i3status-rust.overrideAttrs (final: prev: { - pname = "${prev.pname}-patched"; - - patches = - (prev.patches or []) - ++ [ - # Btrfs support for disk_space block. - ./patches/0001-disk_space-Support-btrfs-backend.patch - ]; -}) diff --git a/pkgs/by-name/i3/i3status-rust-patched/patches/0001-disk_space-Support-btrfs-backend.patch b/pkgs/by-name/i3/i3status-rust-patched/patches/0001-disk_space-Support-btrfs-backend.patch deleted file mode 100644 index 8ef0af2e..00000000 --- a/pkgs/by-name/i3/i3status-rust-patched/patches/0001-disk_space-Support-btrfs-backend.patch +++ /dev/null @@ -1,190 +0,0 @@ -From 78d2936b67064e3b5e700a2859d00ea3dd6eda4c Mon Sep 17 00:00:00 2001 -From: Benedikt Peetz <benedikt.peetz@b-peetz.de> -Date: Sun, 18 May 2025 20:22:04 +0200 -Subject: [PATCH 1/3] disk_space: Support btrfs backend - -Btrfs is too smart for the statvfs based backend (i.e., only counting -blocks leads to wrong numbers). - -For example, a btrfs disk with a lot of de-duplicated blocks (via the copy -on write mechanism) might have a drastically over-reported disk usage. - -The btrfs backend is currently implemented by parsing the output of the -`btrfs filesystem usage --raw` command. This is suboptimal, as this now -relies on the command output not changing. - -Vendoring the algorithm used internally by the `btrfs` command does not -seem to be a reasonable alternative, considering that the code[1] is -rather complex, low level and would require semi-constant maintenance. -Additionally, the c code would need bindings to be usable from rust. - -I assume, that the `btrfs` command output will stay rather similar in -the future, as a lot of tools rely on directly parsing it (see the -various scripts in the issue, this commit fixes). - -[1]: https://github.com/kdave/btrfs-progs/blob/eeab081e9d9fbdf4583122ed1caedf541383cf2d/cmds/filesystem-usage.c#L442 - -Fixes: #1654 ---- - src/blocks/disk_space.rs | 112 +++++++++++++++++++++++++++++++++++---- - 1 file changed, 101 insertions(+), 11 deletions(-) - -diff --git a/src/blocks/disk_space.rs b/src/blocks/disk_space.rs -index 79bfebd27..da0d3f518 100644 ---- a/src/blocks/disk_space.rs -+++ b/src/blocks/disk_space.rs -@@ -12,6 +12,7 @@ - //! `alert` | A value which will trigger critical block state | `10.0` - //! `info_type` | Determines which information will affect the block state. Possible values are `"available"`, `"free"` and `"used"` | `"available"` - //! `alert_unit` | The unit of `alert` and `warning` options. If not set, percents are used. Possible values are `"B"`, `"KB"`, `"KiB"`, `"MB"`, `"MiB"`, `"GB"`, `"Gib"`, `"TB"` and `"TiB"` | `None` -+//! `backend` | The backend to use when querying disk usage. Possible values are `"vfs"` (like `du(1)`) and `"btrfs"` | `"vfs"` - //! - //! Placeholder | Value | Type | Unit - //! -------------|--------------------------------------------------------------------|--------|------- -@@ -63,9 +64,12 @@ - - // make_log_macro!(debug, "disk_space"); - -+use std::cell::OnceCell; -+ - use super::prelude::*; - use crate::formatting::prefix::Prefix; - use nix::sys::statvfs::statvfs; -+use tokio::process::Command; - - #[derive(Copy, Clone, Debug, Deserialize, SmartDefault)] - #[serde(rename_all = "lowercase")] -@@ -76,11 +80,20 @@ pub enum InfoType { - Used, - } - -+#[derive(Copy, Clone, Debug, Deserialize, SmartDefault)] -+#[serde(rename_all = "lowercase")] -+pub enum Backend { -+ #[default] -+ Vfs, -+ Btrfs, -+} -+ - #[derive(Deserialize, Debug, SmartDefault)] - #[serde(deny_unknown_fields, default)] - pub struct Config { - #[default("/".into())] - pub path: ShellString, -+ pub backend: Backend, - pub info_type: InfoType, - pub format: FormatConfig, - pub format_alt: Option<FormatConfig>, -@@ -128,17 +141,9 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> { - loop { - let mut widget = Widget::new().with_format(format.clone()); - -- let statvfs = statvfs(&*path).error("failed to retrieve statvfs")?; -- -- // Casting to be compatible with 32-bit systems -- #[allow(clippy::unnecessary_cast)] -- let (total, used, available, free) = { -- let total = (statvfs.blocks() as u64) * (statvfs.fragment_size() as u64); -- let used = ((statvfs.blocks() as u64) - (statvfs.blocks_free() as u64)) -- * (statvfs.fragment_size() as u64); -- let available = (statvfs.blocks_available() as u64) * (statvfs.block_size() as u64); -- let free = (statvfs.blocks_free() as u64) * (statvfs.block_size() as u64); -- (total, used, available, free) -+ let (total, used, available, free) = match config.backend { -+ Backend::Vfs => get_vfs(&*path)?, -+ Backend::Btrfs => get_btrfs(&path).await?, - }; - - let result = match config.info_type { -@@ -205,3 +210,88 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> { - } - } - } -+ -+fn get_vfs<P>(path: &P) -> Result<(u64, u64, u64, u64)> -+where -+ P: ?Sized + nix::NixPath, -+{ -+ let statvfs = statvfs(path).error("failed to retrieve statvfs")?; -+ -+ // Casting to be compatible with 32-bit systems -+ #[allow(clippy::unnecessary_cast)] -+ { -+ let total = (statvfs.blocks() as u64) * (statvfs.fragment_size() as u64); -+ let used = ((statvfs.blocks() as u64) - (statvfs.blocks_free() as u64)) -+ * (statvfs.fragment_size() as u64); -+ let available = (statvfs.blocks_available() as u64) * (statvfs.block_size() as u64); -+ let free = (statvfs.blocks_free() as u64) * (statvfs.block_size() as u64); -+ -+ Ok((total, used, available, free)) -+ } -+} -+ -+async fn get_btrfs(path: &str) -> Result<(u64, u64, u64, u64)> { -+ const OUTPUT_CHANGED: &str = "Btrfs filesystem usage output format changed"; -+ -+ fn remove_estimate_min(estimate_str: &str) -> Result<&str> { -+ estimate_str.trim_matches('\t') -+ .split_once("\t") -+ .ok_or(Error::new(OUTPUT_CHANGED)) -+ .map(|v| v.0) -+ } -+ -+ macro_rules! get { -+ ($source:expr, $name:expr, $variable:ident) => { -+ get!(@pre_op (|a| {Ok::<_, Error>(a)}), $source, $name, $variable) -+ }; -+ (@pre_op $function:expr, $source:expr, $name:expr, $variable:ident) => { -+ if $source.starts_with(concat!($name, ":")) { -+ let (found_name, variable_str) = -+ $source.split_once(":").ok_or(Error::new(OUTPUT_CHANGED))?; -+ -+ let variable_str = $function(variable_str)?; -+ -+ debug_assert_eq!(found_name, $name); -+ $variable -+ .set(variable_str.trim().parse().error(OUTPUT_CHANGED)?) -+ .map_err(|_| Error::new(OUTPUT_CHANGED))?; -+ } -+ }; -+ } -+ -+ let filesystem_usage = Command::new("btrfs") -+ .args(["filesystem", "usage", "--raw", path]) -+ .output() -+ .await -+ .error("Failed to collect btrfs filesystem usage info")? -+ .stdout; -+ -+ { -+ let final_total = OnceCell::new(); -+ let final_used = OnceCell::new(); -+ let final_free = OnceCell::new(); -+ -+ let mut lines = filesystem_usage.lines(); -+ while let Some(line) = lines -+ .next_line() -+ .await -+ .error("Failed to read output of btrfs filesystem usage")? -+ { -+ let line = line.trim(); -+ -+ // See btrfs-filesystem(8) for an explanation for the rows. -+ get!(line, "Device size", final_total); -+ get!(line, "Used", final_used); -+ get!(@pre_op remove_estimate_min, line, "Free (estimated)", final_free); -+ } -+ -+ Ok(( -+ *final_total.get().ok_or(Error::new(OUTPUT_CHANGED))?, -+ *final_used.get().ok_or(Error::new(OUTPUT_CHANGED))?, -+ // HACK(@bpeetz): We also return the free disk space as the available one, because btrfs -+ // does not tell us which disk space is reserved for the fs. <2025-05-18> -+ *final_free.get().ok_or(Error::new(OUTPUT_CHANGED))?, -+ *final_free.get().ok_or(Error::new(OUTPUT_CHANGED))?, -+ )) -+ } -+} --- -2.49.0 - |
