From 68f164113dee3a205b06bd55f467720243600f83 Mon Sep 17 00:00:00 2001 From: Ainsley Woo <125954904+Kantosaurus@users.noreply.github.com> Date: Tue, 28 Jul 2026 17:20:03 +0800 Subject: [PATCH 1/5] docs: add contributor guide, code of conduct, security policy, and support docs Add the standard community-health files under .github/: CONTRIBUTING.md (development setup for the bare-repo workflow, shell/Python conventions, how to add a setup subscript), CODE_OF_CONDUCT.md (Contributor Covenant 2.1), SECURITY.md (vulnerability reporting policy), and SUPPORT.md (where to get help). --- .github/CODE_OF_CONDUCT.md | 138 +++++++++++++++ .github/CONTRIBUTING.md | 335 +++++++++++++++++++++++++++++++++++++ .github/SECURITY.md | 133 +++++++++++++++ .github/SUPPORT.md | 54 ++++++ 4 files changed, 660 insertions(+) create mode 100644 .github/CODE_OF_CONDUCT.md create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/SECURITY.md create mode 100644 .github/SUPPORT.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..119b33434 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,138 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a +harassment-free experience for everyone, regardless of age, body size, visible or +invisible disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal appearance, +race, caste, color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, +inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community +include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, and + learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, without + their explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional + setting + +### A note specific to this project + +Dusky attracts people at wildly different levels of Linux experience — some arriving from +Windows and installing Arch for the first time, some who have been ricing for a decade. + +**"Just read the wiki" is not an answer here.** Beginners asking basic questions are +welcome and expected. Condescension toward someone who does not yet know what a +compositor is, or gatekeeping about what makes someone a "real" Linux user, is a Code of +Conduct issue, not a personality quirk. + +Equally: disagreement about technical direction is fine and useful. Argue about the +approach, not the person proposing it. + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in response to +any behavior that they deem inappropriate, threatening, offensive, or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, +commits, code, wiki edits, issues, and other contributions that are not aligned to this +Code of Conduct, and will communicate reasons for moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an +individual is officially representing the community in public spaces. Examples of +representing our community include using an official email address, posting via an +official social media account, or acting as an appointed representative at an online or +offline event. + +For this project, community spaces include the GitHub repository (issues, pull requests, +discussions) and the [Dusky Discord server](https://discord.gg/Nv2a7yTBQS). + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to +the community leaders responsible for enforcement by direct message to the maintainer on +the [Dusky Discord server](https://discord.gg/Nv2a7yTBQS), or by opening a +[private report on GitHub](https://github.com/dusklinux/dusky/security/advisories/new). + +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter +of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the +consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing clarity +around the nature of the violation and an explanation of why the behavior was +inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with +the people involved, including unsolicited interaction with those enforcing the Code of +Conduct, for a specified period of time. This includes avoiding interactions in community +spaces as well as external channels like social media. Violating these terms may lead to +a temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained +inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public communication +with the community for a specified period of time. No public or private interaction with +the people involved, including unsolicited interaction with those enforcing the Code of +Conduct, is allowed during this period. Violating these terms may lead to a permanent +ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, +including sustained inappropriate behavior, harassment of an individual, or aggression +toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, +available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/inclusion). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 000000000..ba03981dc --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,335 @@ +# Contributing to Dusky + +Thanks for being here. Dusky is a large, opinionated Arch + Hyprland desktop built over +many months, and it is very much still growing. Bug reports, scripts, docs fixes and +typo corrections are all genuinely welcome. + +This guide is longer than most because Dusky has one genuinely unusual property: **it is +deployed with a bare git repository straight into `$HOME`.** That makes "how do I edit +this safely" a real question, and getting it wrong can scatter files across your home +directory. Read the [Development setup](#development-setup) section before you start. + +--- + +## Table of contents + +- [Ways to help](#ways-to-help) +- [Before you open an issue](#before-you-open-an-issue) +- [Development setup](#development-setup) +- [Testing your change](#testing-your-change) +- [Repository layout](#repository-layout) +- [Shell script conventions](#shell-script-conventions) +- [Python conventions](#python-conventions) +- [Adding a new setup subscript](#adding-a-new-setup-subscript) +- [Adding a new config file](#adding-a-new-config-file) +- [Line endings](#line-endings) +- [Commits and pull requests](#commits-and-pull-requests) +- [Design principles](#design-principles) +- [Licensing](#licensing) + +--- + +## Ways to help + +You do not need to write shell to be useful here. + +| Contribution | Notes | +|---|---| +| **Report a bug** | Use the [bug report form](https://github.com/dusklinux/dusky/issues/new?template=bug_report.yml). Hardware details matter enormously — see below. | +| **Fix a typo or broken doc** | Always welcome, no issue needed. The README and the `Documents/` vault both have rough edges. | +| **Test on hardware nobody has** | AMD-only laptops, hybrid AMD+NVIDIA, unusual displays. Reports of "this worked fine" are also useful data. | +| **Write a script** | See the conventions below. Small, single-purpose, invoked on demand. | +| **Improve the Obsidian vault** | `Documents/pensive/` is a real knowledge base people actually read. | +| **Answer questions on Discord** | Genuinely the highest-leverage thing, and it is where most support happens. | + +--- + +## Before you open an issue + +Roughly nine out of ten Dusky problems trace back to one of three things: **GPU vendor**, +**filesystem**, or **a partially completed `ORCHESTRA.sh` run**. Two steps solve most of +them before an issue is ever needed: + +1. **Re-run the orchestrator.** It is idempotent by design and safe to run repeatedly: + ```bash + ~/user_scripts/arch_setup_scripts/ORCHESTRA.sh + ``` +2. **Run the failing subscript on its own.** Subscripts live in + `~/user_scripts/arch_setup_scripts/scripts/` and each one is independently runnable. + Running just the failing one usually surfaces a much clearer error than the full run. + +If it still fails, open an issue with the subscript name and its full output. + +--- + +## Development setup + +**Do not develop inside the bare repo.** The bare clone described in the README is a +*deployment* mechanism — it checks tracked files directly into your home directory. It is +the right way to *install* Dusky and the wrong way to *edit* it. + +### Recommended: normal clone, separate from your live config + +```bash +git clone https://github.com/dusklinux/dusky.git ~/src/dusky +cd ~/src/dusky +git checkout -b my-change +``` + +Edit here, commit here, open the PR from here. Your running desktop stays untouched until +you deliberately test the change. + +### If you are already running Dusky via the bare repo + +Your live system *is* a checkout, so you can iterate in place and push from it — but be +deliberate about it, because `git checkout -f` against `$HOME` will overwrite local files +without asking. + +```bash +# Convenience alias — add to your shell rc if you do this often. +alias dgit='git --git-dir=$HOME/dusky/ --work-tree=$HOME' + +dgit status # see what you have actually changed +dgit diff # review before committing +dgit checkout -b my-change +``` + +> [!WARNING] +> `dgit checkout -f` and `dgit reset --hard` operate on your entire home directory. +> Take a snapshot first. If you installed via the standard route you already have Snapper +> and BTRFS, so this costs nothing: +> ```bash +> sudo snapper -c root create -d "before dusky edits" +> ``` + +--- + +## Testing your change + +There is no way to unit-test "does this desktop feel right", so testing is mostly manual. +What matters is that you test *something* and say so in the PR. + +**For scripts:** + +```bash +bash -n path/to/script.sh # syntax check — must pass, CI enforces it +shellcheck path/to/script.sh # must be clean, CI enforces it on changed files +./path/to/script.sh # actually run it +./path/to/script.sh # run it AGAIN — it must be safe to re-run +``` + +That second run is not optional. Every script in Dusky is expected to be idempotent +because `ORCHESTRA.sh` re-runs the whole set and users are told re-running is safe. + +**For setup subscripts**, test in a VM or against a fresh snapshot rather than your daily +driver. A GNOME Boxes or `virt-manager` Arch VM is enough for most of them; the +`Documents/pensive/linux/Important Notes/KVM/` notes cover setting one up. + +**For the Python test suite** — `user_scripts/networking/network_throttle/` has real +pytest coverage: + +```bash +cd user_scripts/networking/network_throttle +python -m pytest tests/ -v +``` + +**In your PR, state what you tested on:** GPU vendor, laptop or desktop, filesystem. +"Tested on AMD desktop, BTRFS" tells a reviewer far more than "works for me". + +--- + +## Repository layout + +Everything tracked here lands relative to `$HOME`. + +``` +.config/ application configs (hypr, waybar, rofi, matugen, nvim, …) +├── dusky/version current Dusky version string +├── hypr/ Hyprland config, keybinds, animations, shaders +├── firefox_extentions/ bundled extensions incl. ai_bridge and dusky_sites +└── sddm/ login theme (derived from SilentSDDM) + +user_scripts/ all executable logic — the heart of the project +├── arch_setup_scripts/ +│ ├── ORCHESTRA.sh the conductor: runs ~80 subscripts in order +│ └── scripts/ the subscripts themselves, NNN_name.sh|py +├── arch_iso_scripts/ offline Dusky ISO build pipeline +├── tools/ general-purpose utilities (largest directory) +├── dusky_tui/ terminal UIs for configuration +├── dusky_system/ core desktop behaviours +├── networking/ tailscale, ssh, wireguard, throttling, wifi tooling +├── drives/ drive manager, health, formatting, BTRFS helpers +├── tts_stt/ whisper / parakeet / kokoro speech pipelines +├── hypr/ waybar/ rofi/ per-component helper scripts +├── theme_matugen/ colour generation and template application +└── performance/ audio/ battery/ gaming/ … + +Documents/pensive/ Obsidian knowledge vault — Arch, BTRFS, KVM, GPU passthrough +Pictures/readme_assets/ screenshots used by the README +.git_dusky_list which paths a user's personal backup repo will track +``` + +--- + +## Shell script conventions + +461 shell scripts already exist. Match them. + +**Required:** + +```bash +#!/usr/bin/env bash +set -euo pipefail +``` + +- `#!/usr/bin/env bash`, not `#!/bin/bash` — portability across Arch derivatives. +- `set -euo pipefail` at the top. Around half the tree predates this rule; new scripts + are expected to have it, and adding it to a script you are already touching is welcome. +- **4-space indent**, spaces not tabs. +- **Quote every expansion**: `"$var"`, `"${arr[@]}"`, `"$(cmd)"`. Unquoted paths break the + moment a user has a space in a filename. +- **`shellcheck`-clean.** CI runs ShellCheck at `--severity=error` on every shell file your + PR touches, and that is a hard gate. A separate advisory job reports warnings across the + whole repo without blocking — clearing warnings in files you touch is appreciated but + not required. +- **Idempotent.** Guard before you act: + ```bash + command -v foo >/dev/null 2>&1 || paru -S --needed --noconfirm foo + grep -q 'my_setting' "$conf" || printf 'my_setting=1\n' >> "$conf" + ``` +- **Never hardcode `/home/username`.** Use `$HOME` or `"${XDG_CONFIG_HOME:-$HOME/.config}"`. +- **Ask before destroying.** Anything that formats, deletes, or overwrites user data + prompts first, and says exactly what it will touch. +- **Use `notify-send` for user-facing feedback** on scripts bound to a keybind — the user + has no terminal open to read stdout. +- **`sudo` at the narrowest scope possible.** Do not run a whole script as root when three + lines need it. Never re-exec the script as root implicitly. + +--- + +## Python conventions + +212 Python files, standard-library-first. + +- Python 3, 4-space indent, `snake_case`. +- **Prefer the standard library.** A script that needs `pip install` becomes a support + burden on a rolling-release distro. If you need a third-party package it must be + available in the Arch repos or AUR, and the dependency must be installed by a setup + subscript rather than assumed. +- Must pass `python -m py_compile` (CI enforces this on all Python files). +- Guard entry points with `if __name__ == "__main__":`. +- Keep TUIs responsive — no blocking calls on the render path. + +--- + +## Adding a new setup subscript + +Subscripts live in `user_scripts/arch_setup_scripts/scripts/` and are named +`NNN_short_description.sh` (or `.py`). The number sets execution order. + +1. **Pick a number that reflects the dependency order.** Something that needs the network + must sort after `003_network_connect.sh`; something that themes an app must sort after + the app is installed. Leave gaps — use `145_`, not `144.5_`. +2. **Make it re-runnable.** Detect the already-done state and exit cleanly. +3. **Make it survivable.** If your subscript fails, the rest of the install should still + complete. Do not `exit 1` out of the whole orchestrator for an optional feature. +4. **Be quiet on success, loud on failure.** Users watch ~80 of these scroll past. +5. **Test it twice** — fresh, then again immediately. + +--- + +## Adding a new config file + +Two steps, and the second one is easy to forget: + +1. Add the file under `.config/` (or wherever it belongs relative to `$HOME`). +2. **Add its path to `.git_dusky_list`.** That file drives the personal-backup feature + described in the README — anything not listed there will not be backed up by users who + set up their own Dusky backup repo. A new config that is not in this list silently + fails to persist for them. + +--- + +## Line endings + +All text files in this repo are LF. This is enforced by `.gitattributes`, and CI fails +any PR that introduces CRLF. + +This is not stylistic. A shell script that reaches an Arch machine with CRLF endings dies +at exec time with `/usr/bin/env: 'bash\r': No such file or directory`, which is a +confusing failure to debug from the user side. + +If you are on Windows or WSL, this is handled for you by `.gitattributes` — but verify: + +```bash +file user_scripts/tools/some_script.sh # must NOT say "with CRLF line terminators" +``` + +--- + +## Commits and pull requests + +**Commits:** short, lowercase, present tense, describing the change. Match what is already +in the log — `fps limiter`, `gaming packages`, `sideload ios`. A prefix helps when the +scope is not obvious from the subject: + +``` +fix: waybar colours not regenerating after wallpaper change +feat: add fps limiter toggle to gaming menu +docs: correct drive_manager path in README +``` + +Conventional-commit prefixes are encouraged but not enforced. + +**Pull requests:** + +- One logical change per PR. A typo fix and a new feature should be two PRs. +- Fill in the PR template — especially the hardware you tested on. +- Include a screenshot or short recording for anything visual. This is a ricing project; + reviewers need to see it. +- Do not commit generated artifacts. Anything listed in `.gitignore` + (`matugen.kdl`, `foot-colors.ini`, `active.lua`, `libwaylandgrab.so`, `__pycache__/`) + is generated at runtime and must stay out of the repo. +- Do not commit personal data — hostnames, SSH keys, Tailscale auth keys, WireGuard + private keys, drive UUIDs, wallpapers you did not create. +- Draft PRs are welcome for work in progress. + +Review is by the maintainer and can take a little while — Dusky is maintained alongside a +life. A ping on Discord after a week is completely fine. + +--- + +## Design principles + +Understanding these will save you a rejected PR. + +1. **Lightweight is the point.** Idle RAM sits near 900 MB and disk near 5 GB, fully + configured. Quickshell and similar heavyweight shells are *deliberately* not used; + features are TUI- and script-based instead. A proposal adding a large always-running + daemon needs to justify its footprint. +2. **Invoked, not resident.** Prefer a script that runs on a keybind over a process that + runs forever. +3. **Idempotent everywhere.** Users are explicitly told re-running the installer is safe. + That promise has to hold. +4. **Fail soft.** One broken component must not take the desktop with it. +5. **Auto-detect hardware, but leave the override.** Scripts detect Intel/AMD/NVIDIA, and + users must still be able to set the variable by hand when detection is wrong — real + hardware is messier than any detection heuristic. +6. **Matugen is the single source of colour.** New themed components read from Matugen + templates rather than hardcoding a palette. + +--- + +## Licensing + +Dusky is [MIT licensed](../LICENSE). By submitting a pull request you agree that your +contribution is licensed under the same terms. There is no CLA. + +If you are contributing code adapted from another project, say so in the PR and keep its +copyright notice intact — as Dusky does for +[SilentSDDM](https://github.com/uiriansan/SilentSDDM) and +[MatugenFox](https://github.com/Ubaidullah-Web-Dev/MatugenFox). + +--- + +By participating you agree to abide by the [Code of Conduct](CODE_OF_CONDUCT.md). diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 000000000..202dd4a33 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,133 @@ +# Security Policy + +Dusky installs a desktop environment, configures system services, and runs scripts with +`sudo`. That makes its security posture a real concern rather than a formality, so this +policy is specific rather than boilerplate. + +--- + +## Supported versions + +Dusky is a rolling configuration tracking Arch Linux, which is itself rolling. There are +no maintained release branches. + +| Version | Supported | +|---|---| +| Latest `main` | ✅ Yes | +| Anything older | ❌ No — pull and re-run `ORCHESTRA.sh` | + +Check what you are on with `cat ~/.config/dusky/version`. + +--- + +## Reporting a vulnerability + +**Do not open a public issue for a security vulnerability.** + +Use GitHub's private reporting, which goes only to the maintainer: + +👉 **[Report a vulnerability privately](https://github.com/dusklinux/dusky/security/advisories/new)** + +If that is unavailable to you, DM the maintainer on +[Discord](https://discord.gg/Nv2a7yTBQS) and ask for a private channel. Do not post +details in a public Discord channel. + +**Please include:** + +- What the issue is and what an attacker gains from it +- The specific file and line, if you have it +- Reproduction steps +- Your hardware/config if it is environment-specific + +**What to expect:** this is a solo-maintained hobby project, not a company with an +on-call rotation. Realistically expect an initial response within about a week. You will +be credited in the fix unless you prefer otherwise. Please give a reasonable window for a +fix before disclosing publicly. + +--- + +## What counts as a vulnerability here + +Dusky is configuration and scripts, so the interesting classes are narrower than for an +application. In scope: + +- **Privilege escalation** — a script that lets an unprivileged local user gain root + beyond what the user already intended to authorise. +- **Unsafe `sudo` usage** — running more as root than necessary, writing root-owned files + to user-writable paths, `sudo` on a path an attacker can influence. +- **Command injection** — unquoted expansion of filenames, network responses, clipboard + contents, or window titles into a shell command. +- **Insecure temporary files** — predictable paths in `/tmp` that allow symlink attacks. +- **Credential exposure** — anything writing SSH keys, WireGuard private keys, Tailscale + auth keys, or API tokens to world-readable locations, or logging them. +- **Unintended network exposure** — a setup script binding a service to `0.0.0.0` when it + should be loopback or Tailscale-only, or opening firewall rules more broadly than stated. +- **Insecure downloads** — fetching and executing anything over plain HTTP, or piping an + unverified remote payload into a shell. +- **Committed secrets** — any real key, token, or password found in this repo's history. + +Out of scope: + +- Vulnerabilities in upstream packages (Hyprland, Waybar, Rofi, the kernel). Report those + upstream — though a heads-up is appreciated if Dusky's defaults make one materially worse. +- "Running the installer requires trusting the installer." That is inherent to the tool. +- The bare-repo install overwriting files in `$HOME`. This is documented, intended + behaviour — see the warning in the README. +- Missing hardening you would like to see. That is a feature request, and a welcome one. + +--- + +## Security-relevant things you should know as a user + +These are not bugs. They are properties of what Dusky does, and you should understand +them before installing. + +### The installer runs with elevated privileges + +`ORCHESTRA.sh` orchestrates ~80 subscripts that install packages, enable systemd services, +and modify system configuration. Read what you run. Every subscript in +`~/user_scripts/arch_setup_scripts/scripts/` is a plain, individually readable file, and +that is deliberate. + +### The install overwrites files in your home directory + +```bash +git --git-dir=$HOME/dusky/ --work-tree=$HOME checkout -f +``` + +This force-checks-out tracked files into `$HOME`, overwriting existing ones without +prompting. Back up your existing configs first. + +### AUR packages are built from source + +Dusky uses `paru` to build several AUR packages with CPU-native flags. AUR packages are +user-submitted build scripts. This is normal Arch practice and carries the normal Arch +trust model. + +### The wireless security tooling is for networks you own + +`user_scripts/networking/airmon_ng.sh` and `airmon_ng_gpu.sh` wrap wireless auditing +tools. They exist for testing your own access points. + +> Testing wireless networks you do not own or lack written authorisation to test is a +> criminal offence in most jurisdictions. The maintainer accepts no responsibility for +> misuse. If you do not have explicit authorisation for the network you are pointing this +> at, do not run it. + +### Networking features change your exposure + +The OpenSSH, FTP, WireGuard, Tailscale, VNC, and Cloudflare WARP helpers all alter what +your machine exposes to a network. Understand each before enabling it, particularly on +untrusted networks. Prefer Tailscale-scoped access over publicly-bound services. + +### The offline ISO is distributed outside GitHub + +The Dusky ISO is hosted on Google Drive. It is not signed or checksummed by any automated +release process. If you require verifiable provenance, build the ISO yourself from +`user_scripts/arch_iso_scripts/` rather than downloading the prebuilt image. + +### Do not commit your own secrets + +If you set up the personal-backup feature described in the README, `.git_dusky_list` +controls what gets pushed to *your* repository. Review it before pointing it at a public +remote — SSH keys, WireGuard configs, and drive UUIDs should not end up there. diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 000000000..10911556d --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,54 @@ +# Getting help with Dusky + +Start with the fastest route for your situation. + +## 💬 Discord — start here + +**[discord.gg/Nv2a7yTBQS](https://discord.gg/Nv2a7yTBQS)** + +Most Dusky problems are hardware-specific and get solved in minutes by someone who has hit +the same thing. Installation trouble, "how do I change X", GPU quirks, and general +questions all belong here rather than in an issue. + +## 📺 Video walkthroughs + +- [Installation tutorial](https://youtu.be/OzeFAY_8T8Y) +- [Feature demo](https://youtu.be/JmgvSdEIK8c) + +## 📚 The included documentation + +Dusky ships a substantial Obsidian vault at `~/Documents/pensive/`. It covers Arch +installation, BTRFS and snapshots, GPU passthrough, KVM, NVIDIA, TLP and power tuning, +disk management, and networking. If your question is "how does this Linux thing work", the +answer is quite possibly already written down there. + +## ⌨️ The built-in cheatsheet + +Press `CTRL` + `SHIFT` + `SPACE` for the keybind cheatsheet. Entries are clickable and run +the command directly. + +## 🔧 Self-service troubleshooting + +Two steps fix most breakage: + +```bash +# 1. Re-run the orchestrator — it is idempotent and safe to re-run. +~/user_scripts/arch_setup_scripts/ORCHESTRA.sh + +# 2. If a specific subscript failed, run just that one to get a clearer error. +~/user_scripts/arch_setup_scripts/scripts/.sh +``` + +The scripts are modular — one failure does not mean a broken system, and the rest of the +install generally completes fine. + +## 🐞 Opening an issue + +If you have a **reproducible defect** rather than a support question, open a +[bug report](https://github.com/dusklinux/dusky/issues/new?template=bug_report.yml). +Please include GPU vendor, filesystem, and install method — those three fields resolve +most reports. + +## 🔒 Security issues + +Do not report these publicly. See [SECURITY.md](SECURITY.md). From df1df69e8501ae35d3296d4b0cfe2b9205d19ed9 Mon Sep 17 00:00:00 2001 From: Ainsley Woo <125954904+Kantosaurus@users.noreply.github.com> Date: Tue, 28 Jul 2026 17:20:03 +0800 Subject: [PATCH 2/5] ci: add issue and pull request templates and dependabot config Structured bug-report and feature-request forms that capture GPU vendor, filesystem, and install method (the fields most issues hinge on), a PR template, an issue-template chooser pointing at Discord and the included docs, and a Dependabot config for GitHub Actions. --- .github/ISSUE_TEMPLATE/bug_report.yml | 149 +++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 24 ++++ .github/ISSUE_TEMPLATE/feature_request.yml | 77 +++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 65 +++++++++ .github/dependabot.yml | 18 +++ 5 files changed, 333 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/dependabot.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000..3005745ab --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,149 @@ +name: 🐞 Bug report +description: Something in Dusky is broken — a script fails, a keybind does nothing, theming breaks. +title: "[bug] " +labels: ["bug", "needs-triage"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to file this. + + **Before you continue:** most install problems are hardware-specific and get solved + far faster on [Discord](https://discord.gg/Nv2a7yTBQS). If this is a "it did not + install on my machine" question rather than a reproducible defect, please start there. + + The fields below exist because ~90% of Dusky bugs come down to GPU vendor, + filesystem, or a partially-completed `ORCHESTRA.sh` run. Filling them in accurately + is the single biggest thing you can do to get this fixed quickly. + + - type: checkboxes + id: preflight + attributes: + label: Pre-flight + options: + - label: I searched [existing issues](https://github.com/dusklinux/dusky/issues?q=is%3Aissue) and this is not a duplicate. + required: true + - label: I am on Arch Linux (or an Arch-based distro) with Hyprland. + required: true + - label: I re-ran `~/user_scripts/arch_setup_scripts/ORCHESTRA.sh` and the problem persists. (It is safe to re-run.) + required: false + + - type: textarea + id: what-happened + attributes: + label: What happened + description: What went wrong, and what you expected instead. + placeholder: | + The wallpaper selector opens but selecting a wallpaper does not regenerate the + Matugen colours. I expected the whole system theme to follow the new wallpaper. + validations: + required: true + + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce + description: Exact steps, starting from a state someone else can reach. + placeholder: | + 1. Press SUPER + W to open the wallpaper selector + 2. Pick any wallpaper + 3. Waybar keeps the old colours; ~/.config/waybar/colors.css is not rewritten + validations: + required: true + + - type: input + id: script + attributes: + label: Which script or component? + description: >- + If a setup subscript failed, give its filename. Subscripts live in + `~/user_scripts/arch_setup_scripts/scripts/`. + placeholder: "e.g. 118_matugen_setup.sh, or: waybar, rofi, hypridle, Dusky Control Center" + + - type: textarea + id: logs + attributes: + label: Error output + description: >- + Paste the actual error. For a failing script, re-run just that one script and paste + everything. For a Hyprland-level problem, `journalctl --user -b -e` is usually the + right log. This is rendered as a code block — no backticks needed. + render: shell + + - type: dropdown + id: gpu + attributes: + label: GPU vendor + description: The single most common cause of Dusky bugs. Pick all that apply. + multiple: true + options: + - NVIDIA (proprietary driver) + - NVIDIA (nouveau) + - AMD + - Intel + - Hybrid — Intel + NVIDIA + - Hybrid — AMD + NVIDIA + - Hybrid — Intel + AMD + - Virtual machine / passthrough guest + validations: + required: true + + - type: dropdown + id: filesystem + attributes: + label: Root filesystem + description: Dusky is optimised for BTRFS. ext4 mostly works but is not the tested path. + options: + - BTRFS + - ext4 + - Other (state it in "Anything else") + - Not sure + validations: + required: true + + - type: dropdown + id: install-method + attributes: + label: How did you install Dusky? + options: + - Bare repo clone + ORCHESTRA.sh, on an existing Arch install + - Dusky ISO (offline installer) + - Manually copied individual configs + - Other + validations: + required: true + + - type: dropdown + id: form-factor + attributes: + label: Machine type + description: Several features (battery notifier, TLP, touchpad gestures) are laptop-only. + options: + - Laptop + - Desktop + - Virtual machine + validations: + required: true + + - type: textarea + id: sysinfo + attributes: + label: System info + description: | + Paste the output of: + ``` + fastfetch --logo none + hyprctl version | head -3 + cat ~/.config/dusky/version + ``` + render: shell + validations: + required: true + + - type: textarea + id: extra + attributes: + label: Anything else + description: >- + Screenshots, a recording, dual-boot setup, whether you changed configs by hand, + whether this ever worked before. Drag images straight into this box. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..0a0db09df --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,24 @@ +blank_issues_enabled: false + +contact_links: + - name: 💬 Discord — install help, troubleshooting, general chat + url: https://discord.gg/Nv2a7yTBQS + about: >- + Fastest route for "it did not install", "how do I change X", and anything + hardware-specific. Most setup problems are resolved here in minutes. + Please try Discord before opening an issue. + + - name: 📺 Video walkthrough + url: https://youtu.be/OzeFAY_8T8Y + about: Full install tutorial. Worth watching before reporting an install failure. + + - name: 📚 Included documentation + url: https://github.com/dusklinux/dusky/tree/main/Documents/pensive + about: >- + The repo ships a large Obsidian vault covering Arch install, BTRFS, + snapshots, GPU passthrough, KVM, NVIDIA, TLP and more. Your answer may + already be written down. + + - name: 🖼️ Wallpapers + url: https://github.com/dusklinux/images + about: All 1050+ wallpapers live in a separate repo. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000..5c85e2075 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,77 @@ +name: ✨ Feature request +description: Suggest a script, keybind, Rofi menu, TUI, or quality-of-life improvement. +title: "[feature] " +labels: ["enhancement", "needs-triage"] +body: + - type: markdown + attributes: + value: | + Dusky has a deliberate design constraint worth knowing before you write: + + > **It stays lightweight.** Quickshell and similar heavyweight shells are + > intentionally not used — everything is TUI/script-based to keep idle RAM around + > 900 MB. A proposal that adds a large always-running daemon is unlikely to land + > unless it earns its footprint. + + - type: checkboxes + id: preflight + attributes: + label: Pre-flight + options: + - label: I searched existing issues and this has not already been requested. + required: true + - label: I checked the feature list in the README and this does not already exist. + required: true + + - type: textarea + id: problem + attributes: + label: What problem does this solve? + description: >- + Describe the friction, not the solution. "I have to open a terminal and run three + commands every time I want X" is a far more useful starting point than + "add a button that does X". + validations: + required: true + + - type: textarea + id: proposal + attributes: + label: Proposed behaviour + description: What should it do, and how would you invoke it — keybind, Rofi entry, TUI, Control Center panel? + validations: + required: true + + - type: dropdown + id: surface + attributes: + label: Where does it belong? + multiple: true + options: + - Keybind + - Rofi menu entry + - TUI (dusky_tui) + - Dusky Control Center + - Setup script (ORCHESTRA subscript) + - Waybar module + - Theming / Matugen + - Documentation only + - Not sure + + - type: textarea + id: cost + attributes: + label: Expected resource cost + description: >- + Does this need a background daemon, a Python runtime, an AUR package, a compiled + dependency? Be honest here — it is the main thing that decides whether a feature is + a good fit. "Runs only when invoked, pure bash, no new deps" is the ideal answer. + placeholder: "e.g. one bash script, invoked on keybind, depends on `socat` (already a dependency)" + + - type: checkboxes + id: contribute + attributes: + label: Would you like to implement it? + options: + - label: I am willing to open a PR for this. + required: false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..01e9903c4 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,65 @@ + + +## What does this change? + + + +## Why? + + + +## Type of change + +- [ ] Bug fix +- [ ] New feature / script +- [ ] New setup subscript (`arch_setup_scripts/scripts/`) +- [ ] Theming / visual change +- [ ] Documentation +- [ ] Refactor or cleanup (no behaviour change) + +--- + +## Tested on + + + +- **GPU:** +- **Machine:** +- **Filesystem:** +- **Dusky version:** + +**How I tested it:** + + + +## Checklist + +- [ ] I read [CONTRIBUTING.md](.github/CONTRIBUTING.md) +- [ ] Shell scripts pass `bash -n` and `shellcheck` +- [ ] Python files pass `python -m py_compile` +- [ ] Scripts start with `#!/usr/bin/env bash` and `set -euo pipefail` +- [ ] **The script is safe to run twice** — I actually ran it twice +- [ ] No hardcoded `/home/` paths (`$HOME` used instead) +- [ ] No generated files committed (see `.gitignore`) +- [ ] No personal data committed — SSH keys, auth keys, hostnames, drive UUIDs +- [ ] If I added a config file under `.config/`, I also added it to `.git_dusky_list` +- [ ] If I added a setup subscript, it is numbered correctly and fails soft + +## Screenshots / recording + + + +## Anything reviewers should know + + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..bc297362e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 + +# Dusky has no package manifest to track — Arch packages come from pacman/paru +# at install time, not from a lockfile in this repo. The one thing here that +# *does* have pinned upstream versions is the GitHub Actions workflows, so that +# is all Dependabot watches. Adding npm/pip ecosystems here would only generate +# noise against manifests that do not exist. +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + commit-message: + prefix: "ci" + labels: + - ci + - dependencies + open-pull-requests-limit: 5 From f8932f18f0f397be7eb9c571b7f911599d4be6ba Mon Sep 17 00:00:00 2001 From: Ainsley Woo <125954904+Kantosaurus@users.noreply.github.com> Date: Tue, 28 Jul 2026 17:20:03 +0800 Subject: [PATCH 3/5] build: add lint CI and enforce LF line endings - .github/workflows/lint.yml: check shell syntax (bash -n), Python syntax (py_compile), and CRLF line endings on every push and pull request - .gitattributes: pin all text files to LF so a contributor with core.autocrlf=true cannot commit a script that fails on Arch with /usr/bin/env: 'bash\r' - .editorconfig: match the existing 4-space convention - .gitignore: ignore the graphify-out/ tooling output - renormalize two tracked text files that had CRLF endings --- .editorconfig | 37 + .gitattributes | 91 ++ .github/workflows/lint.yml | 192 ++++ .gitignore | 3 + .../drive_manager/mount_guide_cheet_sheet.txt | 950 +++++++++--------- .../Firefox RAM Optimization on Arch.txt | 534 +++++----- 6 files changed, 1065 insertions(+), 742 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .github/workflows/lint.yml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..c2b90248d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,37 @@ +# https://editorconfig.org +# +# Matched to the conventions already present in the tree (4-space indent across +# both shell and Python) so existing files are not reformatted wholesale. +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 + +# Ecosystem convention is 2 spaces for these; fighting it just creates churn. +[*.{yml,yaml,json,jsonc,kdl,toml}] +indent_size = 2 + +[*.{js,mjs,ts,css}] +indent_size = 2 + +# Markdown: two trailing spaces is a hard line break, so trimming corrupts prose. +[*.md] +trim_trailing_whitespace = false + +# The Obsidian vault is authored in Obsidian, not in an editor honouring this +# file. Leave it entirely alone. +[Documents/**] +trim_trailing_whitespace = false +insert_final_newline = false + +[Makefile] +indent_style = tab + +[*.{png,jpg,jpeg,webp,gif,ico,mp3,wav,ogg,ttf,otf,woff,woff2,so}] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..91d97d4cd --- /dev/null +++ b/.gitattributes @@ -0,0 +1,91 @@ +# ───────────────────────────────────────────────────────────────────────────── +# Line endings — this is load-bearing, do not remove. +# +# Dusky is deployed onto Arch Linux with `git checkout -f` straight into $HOME. +# A shell script that lands with CRLF endings does not "look slightly wrong", +# it hard-fails at exec time: +# +# /usr/bin/env: 'bash\r': No such file or directory +# +# Contributors on Windows or WSL frequently have `core.autocrlf=true`, which +# would otherwise commit CRLF into the repo. Pin the behaviour here rather than +# trusting every contributor's local git config. +# ───────────────────────────────────────────────────────────────────────────── +* text=auto eol=lf + +# Executables and code — always LF, no exceptions. +*.sh text eol=lf +*.bash text eol=lf +*.zsh text eol=lf +.zshrc text eol=lf +.zprofile text eol=lf +*.py text eol=lf +*.lua text eol=lf +*.js text eol=lf +*.mjs text eol=lf +*.ts text eol=lf + +# Config formats consumed by daemons that are not CRLF-tolerant. +*.conf text eol=lf +*.ini text eol=lf +*.toml text eol=lf +*.json text eol=lf +*.jsonc text eol=lf +*.kdl text eol=lf +*.yml text eol=lf +*.yaml text eol=lf +*.css text eol=lf +*.rasi text eol=lf +*.desktop text eol=lf +*.service text eol=lf +*.timer text eol=lf +*.rules text eol=lf +*.glsl text eol=lf +*.frag text eol=lf +*.vert text eol=lf +*.md text eol=lf +*.txt text eol=lf + +# ───────────────────────────────────────────────────────────────────────────── +# Binary — never normalised, never diffed as text. +# ───────────────────────────────────────────────────────────────────────────── +*.png binary +*.jpg binary +*.jpeg binary +*.webp binary +*.gif binary +*.ico binary +*.svg text eol=lf +*.mp3 binary +*.wav binary +*.ogg binary +*.opus binary +*.mp4 binary +*.ttf binary +*.otf binary +*.woff binary +*.woff2 binary +*.so binary +*.o binary +*.zip binary +*.xpi binary +*.gz binary +*.xz binary +*.zst binary + +# ───────────────────────────────────────────────────────────────────────────── +# GitHub Linguist — keep the language bar honest. +# +# `Documents/` is a ~400-file Obsidian notes vault and `Pictures/` is image +# assets. Neither is source code, and without these hints GitHub reports this +# as a prose repository rather than the shell/python project it actually is. +# ───────────────────────────────────────────────────────────────────────────── +Documents/** linguist-documentation +Pictures/** linguist-vendored +*.md linguist-documentation + +# Vendored/derived third-party code — excluded from language stats and from +# "lines changed" noise in PR review. +.config/sddm/** linguist-vendored +**/hyprland-focus-grab-v1-client-protocol.c linguist-generated +**/hyprland-focus-grab-v1-client-protocol.h linguist-generated diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 000000000..2b7b9ac95 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,192 @@ +name: lint + +# Dusky is shell + Python + config, so CI checks the things that actually break +# users: broken syntax in a script that ships straight into $HOME, and CRLF line +# endings that make a script unexecutable on Arch. +# +# Every job here passes on the current tree. If one goes red, it found something. + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: lint-${{ github.ref }} + cancel-in-progress: true + +env: + # Scripts that read their own source as data — e.g. + # selected=$(sed '1,/^# # DATA # #$/d' "$0" | rofi -dmenu) + # They `exit` before the data section, so bash never parses it at runtime, but + # `bash -n` reads the whole file and false-positives on the data. Valid idiom, + # not a bug. Add to this list only for genuine self-data scripts. + SELF_DATA_SCRIPTS: "user_scripts/rofi/emoji.sh" + +jobs: + line-endings: + name: line endings + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Fail if any tracked file has CRLF + run: | + set -euo pipefail + # .gitattributes pins everything to LF. This job is the enforcement. + # A shell script committed with CRLF does not degrade gracefully — it + # dies at exec time on the user's machine with: + # /usr/bin/env: 'bash\r': No such file or directory + # `git ls-files --eol` emits: i/ w/ attr/ \t + # The attr column contains spaces, and paths may too, so split on the + # tab rather than on whitespace. + bad=$(git ls-files --eol | awk -F'\t' '$1 ~ /^i\/(crlf|mixed)/ { print $2 }') + if [ -n "$bad" ]; then + echo "::error::CRLF line endings found in tracked files." + printf '%s\n' "$bad" | while IFS= read -r f; do + echo "::error file=$f::CRLF line endings — must be LF" + done + echo + echo "Fix with:" + echo " git add --renormalize ." + exit 1 + fi + echo "✓ All tracked files use LF." + + shell-syntax: + name: shell syntax + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: bash -n on every tracked shell script + run: | + set -uo pipefail + fail=0 + total=0 + while IFS= read -r f; do + skip=0 + for s in $SELF_DATA_SCRIPTS; do + [ "$f" = "$s" ] && skip=1 + done + [ "$skip" = "1" ] && continue + + total=$((total + 1)) + # -O extglob: several scripts `shopt -s extglob` at runtime and use + # +(...) / !(...) patterns. `bash -n` does not execute the shopt, so + # without this flag valid extglob code is reported as a syntax error. + if ! out=$(bash -O extglob -n "$f" 2>&1); then + fail=$((fail + 1)) + echo "::error file=$f::$out" + fi + done < <(git ls-files '*.sh') + + echo "Checked $total shell scripts, $fail with syntax errors." + [ "$fail" -eq 0 ] + + shellcheck: + name: shellcheck (changed files) + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: ShellCheck files touched by this PR + run: | + set -uo pipefail + base="${{ github.event.pull_request.base.sha }}" + changed=$(git diff --name-only --diff-filter=ACMR "$base" HEAD -- '*.sh' || true) + + if [ -z "$changed" ]; then + echo "No shell scripts changed in this PR." + exit 0 + fi + + echo "Changed shell scripts:" + printf '%s\n' "$changed" + echo + + # --severity=error only. Errors are near-always real defects. Warnings + # and style notes are reported by the advisory full-repo job below, so + # a small PR touching a long legacy script is not ambushed by the + # pre-existing backlog. + rc=0 + while IFS= read -r f; do + [ -f "$f" ] || continue + shellcheck --severity=error --format=gcc "$f" || rc=1 + done <<< "$changed" + exit "$rc" + + shellcheck-full: + name: shellcheck (full, advisory) + runs-on: ubuntu-latest + # Never blocks a merge. This is a standing report of the warning backlog so + # it can be chipped away at, not a gate. + continue-on-error: true + steps: + - uses: actions/checkout@v4 + + - name: Full-repo ShellCheck report + run: | + set -uo pipefail + git ls-files '*.sh' > /tmp/scripts.txt + echo "Scanning $(wc -l < /tmp/scripts.txt) shell scripts at warning severity." + echo + rc=0 + while IFS= read -r f; do + shellcheck --severity=warning --format=gcc "$f" || rc=1 + done < /tmp/scripts.txt + + echo + echo "Advisory only — this job does not block merges." + exit "$rc" + + python-syntax: + name: python syntax + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: py_compile on every tracked Python file + run: | + set -uo pipefail + fail=0 + total=0 + while IFS= read -r f; do + total=$((total + 1)) + if ! out=$(python -m py_compile "$f" 2>&1); then + fail=$((fail + 1)) + echo "::error file=$f::$out" + fi + done < <(git ls-files '*.py') + + echo "Checked $total Python files, $fail with syntax errors." + [ "$fail" -eq 0 ] + + workflow-summary: + name: summary + runs-on: ubuntu-latest + needs: [line-endings, shell-syntax, python-syntax] + if: always() + steps: + - name: Report + run: | + { + echo "### Dusky lint results" + echo + echo "| Check | Result |" + echo "|---|---|" + echo "| Line endings (LF only) | ${{ needs.line-endings.result }} |" + echo "| Shell syntax (\`bash -n\`) | ${{ needs.shell-syntax.result }} |" + echo "| Python syntax (\`py_compile\`) | ${{ needs.python-syntax.result }} |" + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.gitignore b/.gitignore index 3305c707a..d8e93da41 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ __pycache__/ *.pyo *.pyd .pytest_cache/ + +# Knowledge-graph tooling output (graphify) - local analysis artifact, not config +graphify-out/ diff --git a/user_scripts/drives/drive_manager/mount_guide_cheet_sheet.txt b/user_scripts/drives/drive_manager/mount_guide_cheet_sheet.txt index 918325fa6..dcc85dba0 100644 --- a/user_scripts/drives/drive_manager/mount_guide_cheet_sheet.txt +++ b/user_scripts/drives/drive_manager/mount_guide_cheet_sheet.txt @@ -1,475 +1,475 @@ -Filesystem and Storage Architecture Report for Arch Linux (2026) -Executive Summary for Arch Linux in 2026 -The landscape of Linux storage and filesystem architecture has undergone a paradigm shift leading into June 2026, driven by the maturation of the 7.x kernel series, the ubiquitous adoption of PCIe 5.0 Non-Volatile Memory Express (NVMe) solid-state drives, and the deprecation of legacy user-space storage drivers. For modern Arch Linux deployments, the reliance on Filesystem in Userspace (FUSE) modules—historically utilized to bridge cross-platform interoperability gaps—is officially obsolete.1 Modern infrastructure exclusively leverages in-kernel drivers, notably native ntfs (introduced in 7.1) and native exfat, which eliminate the severe context-switching latency and CPU overhead previously associated with interoperability layers while providing robust, POSIX-compliant translation matrices.3 -Simultaneously, the mechanical realities of storage mediums have bifurcated filesystem optimization strategies. The internal logic of modern flash memory controllers, specifically their sophisticated Flash Translation Layers (FTLs), has rendered many historical Linux filesystem optimizations actively detrimental.5 As storage bottlenecks have migrated from the physical NAND flash or magnetic platters to the kernel's block layer and cryptographic workqueues, legacy recommendations regarding complex block alignment flags, synchronous discard operations, and manual garbage collection must be meticulously audited and, in many cases, purged from automation scripts.6 -This exhaustive report provides a definitive, source-grounded decision matrix for filesystem deployment, cryptographic volume management, and mount automation on the current Arch Linux stack. It delineates the strict boundaries between format-time (mkfs) parameters, decryption-time (cryptsetup) configurations, background daemon (systemd) operations, and runtime (mount) flags. By systematically analyzing Btrfs, ext4, NTFS (kernel module), exFAT, VFAT, and F2FS, this document establishes a highly technical framework for safe defaults, conditional performance enhancements, and deprecated practices, ensuring automated drive management scripts are highly optimized, secure, and fully aligned with current upstream kernel behaviors. -Recent Changes Invalidating Legacy Documentation -The rapid evolution of the Linux Virtual File System (VFS) layer and block device management frequently outpaces community documentation. Implementing stale advice from older forum posts or outdated wiki revisions can precipitate severe performance degradation, premature hardware wear, or catastrophic kernel panics. The following architectural shifts fundamentally invalidate historical storage management paradigms. -The deprecation of FUSE for cross-platform filesystems marks a critical performance milestone. Historically, the ntfs-3g and exfat-fuse packages were mandatory for managing Microsoft-formatted drives. These have been superseded by the ntfs and exfat kernel modules.1 Automation scripts invoking mount.ntfs-3g or utilizing FUSE-specific flags will now experience mounting errors or silent fallback failures, particularly in headless daemon environments.8 The native kernel drivers execute operations directly in ring zero, providing near-native Ext4 throughput speeds on NTFS volumes, but they require a distinct set of permission-synthesizing mount flags to function securely, and the mount command must bypass userspace helpers (via the -i flag) to avoid falling back to FUSE ntfs-3g if it is installed on the system.3 -Within the Btrfs ecosystem, the handling of discarded blocks has been entirely overhauled. The discard=async mount option is now the default kernel behavior for Btrfs on solid-state drives.6 Older documentation universally suggested disabling mount-time discard due to I/O stalling, recommending instead the use of a periodic fstrim.timer via systemd. This advice is no longer applicable to Btrfs; the asynchronous implementation intelligently batches freed extents in memory and issues non-blocking TRIM commands exclusively during device idle periods.6 Furthermore, legacy Btrfs SSD layout optimizations, such as ssd_spread, were engineered for first-generation FTLs that struggled with block wear-leveling. Modern SSD controllers manage wear-leveling internally and opaquely. Forcing legacy layout optimizations on modern NVMe drives actively interferes with the hardware controller, increasing logical fragmentation without providing physical endurance benefits.6 -Cryptographic overhead has also shifted. For high-throughput NVMe drives, the default dm-crypt subsystem behavior introduces measurable latency by offloading cryptographic operations to kernel workqueues. The introduction of the no-read-workqueue and no-write-workqueue flags in /etc/crypttab acknowledges that modern multi-core processors can decrypt data inline faster than the kernel can manage the context switch to a background worker thread. Bypassing these queues massively reduces latency for random I/O operations at the cost of a nominal increase in immediate CPU utilization.7 -Finally, legacy safety mechanisms for removable media have been proven harmful. Older guides recommended the flush mount option for VFAT and exFAT USB flash drives to force immediate synchronous writes, ostensibly preventing data corruption if a user abruptly removed the drive. On modern kernels, this flag forces the flash memory controller to write tiny, highly inefficient blocks continuously, halving write throughput and rapidly exhausting the drive's limited write-erase cycle endurance.11 Modern deployments must rely on the standard kernel page cache and enforce software unmounting, utilizing options like errors=remount-ro rather than synchronous flushing. -Drive-Class Architectural Decision Matrix -The physical attributes and firmware logic of the underlying storage medium dictate the correct parameter usage entirely independently of the filesystem overlaid upon it. Understanding the mechanical realities of the drive class is the prerequisite for selecting the appropriate software flags. -Solid-state drives and NVMe storage rely on NAND flash memory gates, which cannot be overwritten directly; a block must be electronically erased before new data can be written. This process is managed by the drive's FTL, which maps logical operating system blocks to physical flash cells. The primary goal for SSDs is reducing "write amplification"—the phenomenon where writing a small amount of data forces the controller to erase and rewrite a large block of surrounding data. Consequently, features like transparent filesystem compression (which reduces the total payload size) and asynchronous TRIM (which informs the controller which blocks are no longer needed by the OS, allowing it to pre-erase them) are critical for SSD health.5 Conversely, attempting to physically defragment an SSD via filesystem utilities is highly destructive, as it burns write cycles moving data around a medium that possesses zero mechanical seek latency.6 -Rotational Hard Disk Drives (HDDs) operate via a mechanical actuator arm traversing magnetic platters. Their primary performance bottleneck is seek time—the physical milliseconds required to move the read/write head to a specific track. Therefore, HDD optimization focuses entirely on ensuring data is written contiguously. Delayed allocation (delalloc) allows the filesystem to hold data in RAM until a large, continuous chunk of free disk space is found, preventing the fragmentation of large files.12 Furthermore, extending the commit interval of journaling filesystems prevents the mechanical arm from constantly interrupting a long sequential write to snap back and update the filesystem journal.12 Features like TRIM (discard) are physically impossible and irrelevant for magnetic media. -Removable USB flash media and SD cards utilize highly inferior NAND flash compared to internal NVMe drives, lacking DRAM caches and featuring rudimentary FTLs. They are highly susceptible to sudden power loss and rapid wear. The optimization strategy here shifts to minimizing metadata writes (via options like lazytime) and ensuring that cross-platform filesystems (like exFAT or VFAT) are mounted with strict error-handling constraints (errors=remount-ro) to freeze the filesystem the moment corruption is detected, preventing cascaded data loss.13 -Global Drive-Class Recommendations -Drive Class - Baseline Architecture Strategy - Critical Optimization Tweaks - Toxic Operations to Avoid - Internal SSD / NVMe - Rely on asynchronous TRIM (discard=async for Btrfs, hybrid for F2FS) or systemd's fstrim.timer (ext4). Focus on reducing write amplification. - noatime, lazytime. Increase journal commit intervals. Enable transparent compression to reduce flash cell wear. - Defragmentation tools (e.g., autodefrag), synchronous discard, legacy ssd_spread flags. - Rotational HDD - Optimize for continuous sequential read/write operations to prevent actuator arm thrashing and seek latency. - autodefrag (Btrfs only), delalloc (ext4), commit=20. Enable compression to increase logical throughput by packing more data per physical track. - Any form of discard or TRIM. Btrfs nodatacow on small files (causes severe mechanical fragmentation). - External USB / Flash - Maximize cross-operating-system interoperability. Protect against abrupt physical disconnects while minimizing metadata wear. - Synthesize permissions (uid=1000, gid=1000), enforce Windows compliance (windows_names), use errors=remount-ro. - The flush option (destroys throughput and hardware endurance). Synchronous journaling. - Shared Windows Interop - Utilize kernel-native translation modules (ntfs, exfat) to map POSIX standards to Windows metadata logic. - umask=022, iocharset=utf8, prealloc (for large media transfers). - The force flag (corrupts Windows hibernation and fast-startup dirty bits). - File-System-by-File-System Implementation Matrix -The following sections exhaustively define the parameters applicable to modern filesystems, meticulously categorizing them by implementation layer: format-time (mkfs), decryption-time (cryptsetup), background services (systemd), and runtime (mount). -Btrfs (B-Tree Filesystem) -Btrfs is an advanced Copy-on-Write (CoW) filesystem engineered for fault tolerance, atomic snapshotting, and robust subvolume management. Unlike traditional filesystems that overwrite data in place, Btrfs writes modifications to new blocks and updates the metadata pointers, ensuring that a crash during a write operation never corrupts the original data. -A critical architectural constraint of Btrfs is the scope of its mount options. The vast majority of Btrfs mount options apply globally to the entire physical filesystem, not to individual subvolumes. The Linux VFS layer parses the mount options provided when the first subvolume of a Btrfs partition is mounted; subsequent subvolume mounts from the same partition will silently inherit these global options, ignoring conflicting flags provided in their specific mount commands.15 Therefore, it is architecturally impossible to set compress=zstd on a /home subvolume and nodatacow on a /var subvolume if they reside on the same backing block device.6 Furthermore, option ordering matters during evaluation; the system processes options from left to right, and the final occurrence of conflicting options takes precedence.15 -Btrfs Configuration Parameters - - -Option Name - Implementation Layer - Classification - Explanation & Mechanical Behavior - Version / Confidence Note - ssd / nossd - Mount - Auto-detected Default - Modifies block allocation heuristics by removing rotational seek penalties. Automatically triggered if the kernel detects a non-rotational medium. Do not specify manually.6 - Standard behavior. High confidence. - discard=async - Mount - Safe Default - Gathers freed extents in a memory queue and dispatches non-blocking TRIM commands to the SSD controller during idle I/O periods.6 - Default since Kernel 6.2+. Replaces fstrim.timer. - space_cache=v2 - Mount - Safe Default - Replaces the legacy free-space tracking mechanism with a highly optimized, persistent B-tree, drastically reducing mount times and CPU overhead during block allocation.16 - Default on modern Arch. v1 is heavily deprecated. - compress=zstd:3 - Mount - Performance Tweak - Transparently compresses data payloads using the Zstandard algorithm before writing to disk. Reduces SSD write amplification and increases effective HDD throughput. Level 3 is the optimal balance of speed and ratio.6 - Supported since Kernel 5.1+. Automatically disables nodatacow. - compress-force=zstd:3 - Mount - Conditional Tweak - Bypasses the filesystem's early heuristic checks (which abort compression if the first few bytes appear incompressible) and forces a compression attempt on the entire payload.6 - Use only for highly compressible datasets (e.g., text, logs). Wastes CPU on pre-compressed video files. - nodatacow - Mount - Conditional Tweak - Disables Copy-on-Write semantics. Data is overwritten in-place. Implicitly disables both data checksumming (nodatasum) and transparent compression.6 - Mandatory for VM images and heavy databases (PostgreSQL/SQLite) to prevent catastrophic internal fragmentation.12 - autodefrag - Mount - Rotational Media Only - Scans for small, random writes and queues them for background physical defragmentation into contiguous blocks.12 - Highly toxic to SSDs. Accelerates flash cell wear for zero mechanical benefit. Mandatory for HDDs.6 - subvol=/path - Mount - Generic Mount Option - Instructs the VFS layer to mount a specific subvolume path as the root of the designated mount point, overriding the partition's default subvolume ID.6 - Overrides subvolid if both are specified and conflict. - Btrfs Baseline Recommendations -* 1. SSD/NVMe Baseline: discard=async,space_cache=v2,compress=zstd:3,noatime. (Relies on background TRIM and compression to extend flash life). -* 2. Rotational HDD Baseline: space_cache=v2,compress=zstd:3,noatime,autodefrag. (Relies on defragmentation to reduce seek times; compression packs more data per magnetic track). -* 3. Removable USB Media: Not recommended. Btrfs metadata overhead and CoW architecture are too heavy for low-tier flash controllers without dedicated DRAM caches. -* 4. Shared Windows Interop: Incompatible. Windows requires third-party, highly unstable drivers to read Btrfs. -* 5. Encrypted Drives: Inherits the underlying SSD/HDD baseline. Btrfs is unaware of the lower dm-crypt layer. -* 6. Options to Avoid: discard=sync, ssd_spread (interferes with modern FTLs), space_cache=v1. -Ext4 (Fourth Extended Filesystem) -Ext4 remains the industry gold standard for traditional, high-performance, non-CoW Linux filesystems. It utilizes a robust journaling architecture to ensure metadata consistency in the event of power loss, logging intended changes to a dedicated disk area before committing them to the primary filesystem structure. Because it does not utilize Copy-on-Write, it is highly resilient against the severe fragmentation issues that plague Btrfs when hosting virtual machine images or active databases. -Unlike Btrfs, Ext4's native discard mount option historically operated synchronously. When a file was deleted, the kernel would immediately issue a TRIM command and halt the I/O queue until the SSD controller confirmed the block was erased. On heavy workloads, this introduces massive latency spikes. Therefore, the modern architectural standard for Ext4 completely abandons the discard mount flag in favor of systemd's scheduled fstrim.timer, which handles garbage collection in bulk during off-peak hours.17 -Ext4 Configuration Parameters - - -Option Name - Implementation Layer - Classification - Explanation & Mechanical Behavior - Version / Confidence Note - noatime - Mount - Safe Default - Eliminates the legacy POSIX requirement to update a file's access timestamp (i_atime) upon every read operation. Prevents the "write-after-every-read" performance penalty.12 - Replaces the kernel default relatime. Safe for all modern systems.19 - lazytime - Mount - Performance Tweak - Caches updates to access, modification, and creation timestamps purely in RAM. The kernel flushes these to the physical disk only when the inode undergoes other metadata changes or during unmount.21 - Excellent for reducing metadata wear on flash drives and reducing seek activity on HDDs. - delalloc - Mount - Safe Default - Delayed allocation. The kernel accumulates file data in memory caches, analyzing the total size before searching the physical disk for a single, contiguous block of free space.12 - Default behavior. Drastically minimizes fragmentation for large file writes. - commit=20 - Mount - Performance Tweak - Dictates the frequency (in seconds) at which the kernel flushes the in-memory journal to the physical disk. Ext4 defaults to 5 seconds; 20 seconds drastically reduces write operations.12 - Highly recommended for reducing SSD wear. Risk: A sudden power loss guarantees up to 20 seconds of data loss. - fstrim.timer - Systemd - Scheduled Service - A background systemd daemon that issues a batched TRIM command across the entire filesystem block structure, typically executing weekly.17 - Preferred over mount-time discard for Ext4 to prevent synchronous I/O queue stalling. - Ext4 Baseline Recommendations -* 1. SSD/NVMe Baseline: noatime,lazytime,delalloc,commit=20. (Relies on fstrim.timer for garbage collection. Maximizes throughput by delaying metadata writes). -* 2. Rotational HDD Baseline: noatime,lazytime,delalloc,commit=20. (Extending the commit interval prevents the actuator arm from constantly seeking back to the journal partition). -* 3. Removable USB Media: noatime,lazytime,commit=60. (While Ext4 is not ideal for cross-platform USBs, extending the commit to 60 seconds drastically saves cheap flash cells from journal burnout). -* 4. Shared Windows Interop: Incompatible without third-party Windows software. -* 5. Encrypted Drives: Standard baselines apply. Ext4's lack of CoW makes it the highest-performing filesystem inside a LUKS container for heavy database workloads.12 -* 6. Options to Avoid: discard (causes synchronous I/O stalling), data=journal (forces all file data through the journal, halving write speed).23 -NTFS (Native NTFS Kernel Module in Linux 7.1+) -Introduced in kernel 7.1, the rewritten native kernel ntfs module completely replaces the older ntfs3 Paragon driver and the legacy userspace ntfs-3g driver.3 NTFS is the proprietary filesystem of Microsoft Windows. Because the NTFS metadata structure possesses no concept of Linux user IDs, group IDs, or POSIX execution bits, the Linux VFS must synthesize these permissions mathematically at the exact moment the drive is mounted. Failure to explicitly define these translation parameters results in the entire drive defaulting to root ownership, rendering it completely read-only for standard users.25 -Furthermore, Windows enforces strict file naming conventions that Linux does not share. Linux allows almost any character except a forward slash and a null byte in a filename. If a Linux user creates a file named report?.txt on an NTFS drive, Windows will view the NTFS Master File Table (MFT) as corrupted and demand a disk check upon reboot. Modern ntfs parameters must safeguard against this, and the mount command must bypass userspace helpers (using the -i flag) to prevent calling legacy ntfs-3g helpers.1 -NTFS Configuration Parameters - - -Option Name - Implementation Layer - Classification - Explanation & Mechanical Behavior - Version / Confidence Note - uid=, gid= - Mount - Mandatory - Explicitly defines the integer User ID and Group ID that will be synthesized as the owner of all files and directories on the NTFS volume.3 - Typically set to uid=1000,gid=1000 for the primary system user.25 - umask=, dmask=, fmask= - Mount - Mandatory - Establishes the inverse permission bitmask. dmask applies to directories, fmask applies to files. A umask=022 yields 755 permissions for directories and 644 for files.3 - Essential for preventing the volume from becoming world-writable (777). - windows_names - Mount - Compatibility Tweak - Enforces strict Windows naming restrictions within the Linux VFS, actively blocking the creation of files containing characters like *, ?, <, >, or reserved DOS names like CON.1 - Prevents MFT index corruption when the drive is returned to a Windows host.12 - iocharset=utf8 - Mount - Compatibility Tweak - Instructs the driver to translate wide-character NTFS path strings into standard UTF-8 for the Linux terminal.3 - Safe default. Prevents encoding errors on complex filenames.27 - prealloc - Mount - Performance Tweak - Instructs the kernel to aggressively preallocate contiguous disk sectors when a file's size is detected as increasing during a write operation.3 - Highly recommended to combat severe fragmentation during large media downloads or transfers.3 - force - Mount - Highly Toxic - Overrides the kernel's safety lock and mounts the volume read-write even if the NTFS "dirty bit" is flagged.3 - Never use. Bypassing the dirty bit on a hibernated Windows drive guarantees catastrophic filesystem corruption.24 - NTFS Baseline Recommendations -* 1. SSD/NVMe Baseline: Native Linux filesystems are vastly superior. If forced to use NTFS internally, use: uid=1000,gid=1000,umask=022,noatime,prealloc (making sure to mount with -i to bypass userspace helpers). -* 2. Rotational HDD Baseline: uid=1000,gid=1000,umask=022,noatime,prealloc. (Preallocation is vital to prevent physical fragmentation). -* 3. Removable USB Media: exFAT is preferred for flash media, but NTFS works with standard parameters. -* 4. Shared Windows Interop Baseline: uid=1000,gid=1000,umask=022,windows_names,iocharset=utf8,prealloc. (Ensures perfect cross-platform read/write compliance without corrupting the MFT).12 -* 5. Encrypted Drives: NTFS inside LUKS is possible but highly niche. Parameters remain identical. -* 6. Options to Avoid: force (corrupts hibernated drives), ntfs-3g (legacy FUSE driver, high CPU overhead), ntfs3 (legacy Paragon driver). -exFAT (Extensible File Allocation Table) -exFAT is the modern industry standard for high-capacity external USB drives and SDXC cards, designed explicitly by Microsoft to replace FAT32 without inheriting the immense metadata overhead of NTFS. Supported natively in the Linux kernel, it is the optimal choice for cross-platform flash storage.4 Like NTFS, exFAT lacks native POSIX ownership concepts and requires mathematical permission synthesis at mount time. -Because exFAT is heavily utilized on external, removable flash drives—which are physically prone to being unexpectedly unplugged or suffering from cheap, degrading flash memory—the kernel must be instructed on how to handle sudden physical layer corruption gracefully. -exFAT Configuration Parameters - - -Option Name - Implementation Layer - Classification - Explanation & Mechanical Behavior - Version / Confidence Note - uid=, gid=, umask= - Mount - Mandatory - Performs the identical permission synthesis operations as the NTFS module, ensuring the mounted volume is accessible to the current Linux user.29 - Use uid=1000,gid=1000,dmask=022,fmask=133 to grant full directory traversal without making files executable. - errors=remount-ro - Mount - Safety Tweak - Instructs the kernel's block layer to instantly lock the volume into read-only mode the millisecond filesystem corruption or a physical read/write error is detected.14 - Critical safety mechanism for degraded USB flash drives, preventing cascaded data loss. - discard - Mount - Conditional - Passes TRIM commands through the exFAT driver to the underlying flash medium.17 - Only effective if the USB enclosure firmware explicitly supports UASP (USB Attached SCSI Protocol) and TRIM pass-through. Otherwise, it throws errors. - exFAT Baseline Recommendations -* 1. SSD/NVMe Baseline: Do not use exFAT for internal OS drives. It lacks journaling and is highly fragile under parallel I/O loads. -* 2. Rotational HDD Baseline: Do not use exFAT for internal mechanical drives. -* 3. Removable USB Media Baseline: uid=1000,gid=1000,dmask=022,fmask=133,errors=remount-ro,iocharset=utf8. (The absolute standard for USB thumb drives over 32GB). -* 4. Shared Windows Interop: See Removable USB Media Baseline. -* 5. Encrypted Drives: Incompatible. Removable drives needing encryption should use LUKS with a native Linux FS, sacrificing Windows interop. -* 6. Options to Avoid: Attempting to mount via the deprecated exfat-fuse user-space utility.2 -VFAT / FAT32 -VFAT is a legacy filesystem strictly bounded by a maximum file size of 4GB. In modern Arch Linux deployments, its exclusive purpose is formatting the EFI System Partition (ESP) required by UEFI firmware for booting the operating system, or formatting very small (<32GB) legacy USB sticks.13 -A deeply entrenched piece of legacy advice for VFAT was the use of the flush mount option for USB flash drives. This option was historically meant to protect users who yanked USB drives out without safely unmounting them by forcing the kernel to synchronize data to the flash drive upon every single write syscall. On modern kernels and modern flash drives, the flush option forces the flash memory controller to write tiny, unaligned metadata blocks continuously. This specific interaction destroys the drive's endurance and demonstrably cuts write throughput in half compared to relying on the standard kernel page cache.11 -VFAT Configuration Parameters - - -Option Name - Implementation Layer - Classification - Explanation & Mechanical Behavior - Version / Confidence Note - shortname=mixed - Mount - Compatibility Tweak - Dictates the algorithm the kernel uses to generate and display legacy 8.3 character DOS filenames.13 - Safe default. Replaces the deprecated nocase flag.13 - utf8 - Mount - Compatibility Tweak - Encodes Unicode names in UTF-8 format for proper display in the Linux terminal.32 - Standard requirement for modern locales. - flush - Mount - Highly Toxic - Forces immediate synchronization of data and metadata to the physical flash cells upon every VFS write operation.11 - Never use. Devastates flash memory throughput and physical endurance.11 Rely on proper software unmounting. - VFAT Baseline Recommendations -* 1. SSD/NVMe Baseline: Only utilized for the /boot/efi partition. Use fmask=0137,dmask=0027 to lock down bootloader security. -* 2. Removable USB Media: uid=1000,gid=1000,shortname=mixed,utf8,errors=remount-ro. (Only use for drives <32GB; otherwise, utilize exFAT). -* 3. Options to Avoid: flush (destroys drive health and speed). -F2FS (Flash-Friendly File System) -F2FS is an advanced, highly specialized Log-Structured File System engineered from the ground up for NAND-based flash memory (NVMe, SATA SSDs, eMMC, and SD cards) equipped with an internal Flash Translation Layer (FTL). Unlike traditional filesystems that overwrite data in place, F2FS continually appends new data to the end of a log, turning random writes into fast sequential writes and significantly reducing the write amplification that destroys flash cells over time.5 -Because it continuously appends data, F2FS requires a robust Garbage Collection (GC) mechanism to reclaim space from old, invalidated data blocks. Modern F2FS implementations have introduced Asynchronous Threaded Garbage Collection (atgc), which moves this intense consolidation process into a non-blocking background thread. However, F2FS operates uniquely regarding compression: unlike Btrfs, F2FS compression does not immediately expose the saved space to the user. Instead, it reserves the logical blocks to strictly minimize the amount of physical data pushed to the flash cells, maximizing hardware lifespan over perceived capacity.5 -F2FS Configuration Parameters - - -Option Name - Implementation Layer - Classification - Explanation & Mechanical Behavior - Version / Confidence Note - compression - mkfs (Format) - Mandatory Prerequisite - Compression must be physically enabled at the block level during filesystem creation (mkfs.f2fs -O compression) before it can be utilized by mount flags.5 - Cannot be enabled retroactively without reformatting. - compress_algorithm=zstd:6 - Mount - Performance Tweak - Instructs the VFS to utilize the Zstandard algorithm at compression level 6. This provides a highly favorable ratio, drastically reducing physical wear on the NAND gates.5 - Only operates on files flagged via chattr +c or globally via compress_extension=*. - compress_chksum - Mount - Safety Tweak - Cryptographically hashes and verifies compressed blocks during read operations to actively prevent silent data corruption.5 - Essential safety net; compression makes bit-rot highly destructive. - atgc - Mount / Kernel - Performance Tweak - Enables the superior Asynchronous Threaded Garbage Collector. Warning: If F2FS is the root partition (/), placing this in /etc/fstab will cause a systemd remount failure. It must be passed as a bootloader kernel parameter (rootflags=atgc).5 - Resolves severe blocking I/O spikes associated with legacy synchronous F2FS garbage collection. - gc_merge - Mount - Performance Tweak - Allows the kernel to merge foreground garbage collection tasks, executing them asynchronously.5 - High-performance complement to atgc. - lazytime - Mount - Safe Default - Defers file timestamp updates to RAM. Critical for log-structured filesystems to prevent generating endless tiny log appends just to record read access times.5 - Essential for F2FS endurance. - nodiscard - Mount - Conditional - F2FS utilizes a highly intelligent hybrid asynchronous TRIM by default. If a user strictly prefers utilizing systemd's periodic fstrim.timer, they must explicitly pass nodiscard to stop F2FS from competing with the timer.5 - Rely on the F2FS default unless specifically troubleshooting firmware TRIM bugs. - F2FS Baseline Recommendations -* 1. SSD/NVMe Baseline: compress_algorithm=zstd:6,compress_chksum,atgc,gc_merge,lazytime. (Requires rootflags=atgc in the bootloader if used for the root filesystem). -* 2. Rotational HDD Baseline: Incompatible. Log-structured filesystems cause extreme mechanical actuator thrashing on magnetic drives. -* 3. Removable USB Media: lazytime,atgc,gc_merge. (Excellent for extending the life of SD cards and USB drives, provided they are only used on Linux machines). -* 4. Shared Windows Interop: Incompatible. Windows cannot read F2FS. -* 5. Encrypted Drives: Standard baselines apply. F2FS works excellently under LUKS to reduce cryptographic write amplification. -* 6. Options to Avoid: discard=sync (stalls the log appender). -Encrypted Volumes (LUKS2 / dm-crypt) -The Linux Unified Key Setup (LUKS) operates as a block-device translation layer (dm-crypt), situated between the raw physical hardware and the filesystem (VFS) layer. Because the encryption layer wraps the raw blocks, it dictates a strict operational hierarchy: cryptographic parameters are entirely managed by cryptsetup during formatting and by /etc/crypttab during the boot unlock phase, before the filesystem is mounted by fstab.7 -A monumental bottleneck in modern Linux storage involves the intersection of dm-crypt and PCIe 4.0/5.0 NVMe drives. Historically, dm-crypt utilized kernel workqueues to process cryptographic decryption. A CPU core would request data, and the kernel would offload the decryption math to a background worker thread. On mechanical drives or SATA SSDs, the drive's latency was so high that the CPU context-switch time was negligible. However, modern NVMe drives operate at single-digit microsecond latencies. The kernel's context switch to the workqueue now takes longer than the drive takes to fetch the data, severely bottlenecking random I/O performance.7 -Cryptographic Parameter Matrix - - -Option Name - Implementation Layer - Classification - Explanation & Mechanical Behavior - Version / Confidence Note - --sector-size 4096 - mkfs (Format) - Performance Tweak - Passed to cryptsetup luksFormat. The legacy dm-crypt default was 512 bytes. Modern NVMe drives and high-capacity HDDs utilize 4K native physical sectors. Forcing 4096 bytes aligns the cryptographic payload perfectly with the physical hardware gates, eliminating the massive read-modify-write performance penalty.35 - Cannot be altered without totally destroying and recreating the LUKS container. - no-read-workqueue - crypttab (Unlock) - Performance Tweak - Bypasses the kernel's cryptographic read workqueues. Forces the decryption mathematics to execute synchronously inline on the exact CPU core that requested the I/O operation.7 - Mandatory for NVMe drives. Can increase random I/O speeds by up to 30%. Adds slight CPU overhead.10 - no-write-workqueue - crypttab (Unlock) - Performance Tweak - Identical to above, but applies to the write path, enforcing inline encryption before dispatching to the NVMe controller.7 - Apply together with no-read-workqueue in /etc/crypttab. - discard / --allow-discards - crypttab (Unlock) - Conditional Tradeoff - Instructs the dm-crypt block layer to pierce the encryption veil and pass TRIM commands from the upper filesystem down to the physical SSD controller.7 - Security Tradeoff: Passing TRIM allows a forensic attacker to see exactly which blocks are physically empty, breaking plausible deniability and mapping filesystem usage. Performance Tradeoff: Blocking TRIM causes severe write amplification on the SSD over time. For non-state-secret hardware, the physical performance preservation outweighs the metadata security leak.7 - The "Do Not Use By Default" List -The following VFS flags and operational strategies persist in outdated wikis, automated scripts, and community lore. They pose active, quantifiable threats to system performance, hardware longevity, or data integrity on the current Arch Linux stack. -1. discard=sync (or bare discard on ext4): Forces the kernel to block the entire I/O queue while waiting for the SSD controller to physically erase a flash block. This results in severe system stalling during large file deletions. Rely exclusively on Btrfs's discard=async or systemd's scheduled fstrim.timer.6 -2. flush on VFAT/FAT32: Ostensibly a safety feature for USB drives, this flag forces every tiny metadata update (such as updating an access time) to immediately commit to the physical flash cells. It destroys USB drive throughput, cutting speeds by 50% or more, and rapidly burns through the drive's limited write-erase endurance.11 -3. force on NTFS: Ignores the NTFS volume's internal dirty bit. If a Windows partition is placed into hibernation or utilizes "Fast Startup," its metadata is locked. Forcing a read-write mount from Linux will brutally corrupt the Windows Master File Table (MFT).24 -4. space_cache=v1 on Btrfs: An obsolete, highly fragmented caching mechanism. Ensure all automation scripts specify space_cache=v2.16 -5. autodefrag on SSDs/NVMes: Forces the Btrfs filesystem to continuously rewrite data blocks into contiguous alignments. Because solid-state drives possess zero mechanical read heads, contiguous logical alignment provides zero physical read-speed benefit. This flag only serves to continuously burn through the limited write-lifespan of the NAND flash gates.6 -6. Mixing nodatacow and compress: On Btrfs architectures, transparent compression strictly requires Copy-on-Write logic to function. Passing nodatacow implicitly and silently disables all compression and checksumming algorithms.6 Attempting to mix these flags in a script indicates a fundamental misunderstanding of the filesystem's topology. -Mount Automation Script Matrix (TOML Configurations) -The following matrices synthesize this exhaustive research into precise, parseable TOML blocks specifically engineered to be ingested by automation scripts (such as a Python drive_manager.py). These parameters translate directly into highly optimized kernel VFS configurations.12 -1. The NVMe System / Browser Partition (Btrfs) -High-speed flash optimization. Designed for maximum throughput, relying on modern SSD FTLs and inline decryption. - - - - - - -Ini, TOML -[drives.nvme_system] -type = "PROTECTED" -mountpoint = "/mnt/system" -outer_uuid = "0a52e1bb-4fa0-4138-a150-f59467903e22" -inner_uuid = "1adeb61a-0605-4bbc-8178-bb81fe1fca09" -hint = "system_key" -fstype = "btrfs" -mount_options = -# CRITICAL: Ensure /etc/crypttab includes 'no-read-workqueue,no-write-workqueue,discard' -# for the outer_uuid block device to eliminate context-switch latency on NVMe hardware. - -2. The Internal Media Storage (Ext4) -Mass storage optimization. Focused on reducing metadata writes and preventing fragmentation of massive sequential files. - - - - - - -Ini, TOML -[drives.media_ssd] -type = "PROTECTED" -mountpoint = "/mnt/media" -outer_uuid = "98353f6a-b21b-4966-9f57-948678bde66d" -inner_uuid = "a7230e67-34e8-4cd2-981d-ea02d1253539" -hint = "media_key" -fstype = "ext4" -mount_options = -# NOTE: Relies exclusively on systemd's fstrim.timer for garbage collection. - -3. The Rotational Hard Disk Drive Archive (Btrfs) -Mechanical drive optimization. Targeting the absolute mitigation of physical actuator arm seek latency. - - - - - - -Ini, TOML -[drives.rotational_archive] -type = "PROTECTED" -mountpoint = "/mnt/archive" -outer_uuid = "953a147e-a346-4fea-91f4-a81ec97fa56a" -inner_uuid = "46798d3b-cda7-4031-818f-37a06abbeb37" -hint = "archive_key" -fstype = "btrfs" -mount_options = - -4. Shared Windows / Interoperability Drive (NTFS) -Cross-platform safety, synthesized POSIX compliance, utilizing kernel-native rendering. - - - - - - -Ini, TOML -[drives.windows_shared] -type = "SIMPLE" -mountpoint = "/mnt/windows" -outer_uuid = "848A215E8A214E4C" -fstype = "ntfs" # Modern in-kernel module; bypassed FUSE via -i mount flag -mount_options = - -5. Flash-Native Removable Storage (F2FS) -Maximum NAND endurance architecture for SD Cards and unencrypted USB Flash Drives. - - - - - - -Ini, TOML -[drives.usb_flash] -type = "SIMPLE" -mountpoint = "/mnt/usb" -outer_uuid = "C4A2B1D3E5" -fstype = "f2fs" -mount_options = -# NOTE: If utilizing F2FS on the primary boot drive, ensure 'rootflags=atgc' -# is present in the bootloader kernel parameters to prevent systemd remount failures. - -Works cited -1. [HowTo] Mount NTFS correctly under Linux - Tutorials, accessed June 15, 2026, https://forum.manjaro.org/t/howto-mount-ntfs-correctly-under-linux/177221 -2. Kernel-mounted vs FUSE-mounted exfat filesystem - Unix & Linux Stack Exchange, accessed June 15, 2026, https://unix.stackexchange.com/questions/761324/kernel-mounted-vs-fuse-mounted-exfat-filesystem -3. NTFS — The Linux Kernel documentation, accessed June 15, 2026, https://www.kernel.org/doc/html/v6.1/filesystems/ntfs3.html -4. How to enable exFAT for Ubuntu 20.04, accessed June 15, 2026, https://askubuntu.com/questions/1234755/how-to-enable-exfat-for-ubuntu-20-04 -5. F2FS - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/F2FS -6. BTRFS SPECIFIC MOUNT OPTIONS — BTRFS documentation, accessed June 15, 2026, https://btrfs.readthedocs.io/en/latest/ch-mount-options.html -7. dm-crypt/Specialties - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/Dm-crypt/Specialties -8. udisks - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/Udisks -9. NTFS — The Linux Kernel documentation, accessed June 15, 2026, https://www.kernel.org/doc/html/v6.2/filesystems/ntfs3.html -10. Disable read/write workqueue for Ubuntu Full-Disk-Encryption, accessed June 15, 2026, https://unix.stackexchange.com/questions/724104/disable-read-write-workqueue-for-ubuntu-full-disk-encryption -11. 198605 – Mounting vfat fs from usb flash drives with "flush" option causes slow write performance - Kernel Bugzilla, accessed June 15, 2026, https://bugzilla.kernel.org/show_bug.cgi?id=198605 -12. drives.toml -13. VFAT - The Linux Kernel documentation, accessed June 15, 2026, https://docs.kernel.org/filesystems/vfat.html -14. How to mount an exFAT external drive , ensuring user permissions, without using /etc/fstab ? : r/linuxquestions - Reddit, accessed June 15, 2026, https://www.reddit.com/r/linuxquestions/comments/1ksf730/how_to_mount_an_exfat_external_drive_ensuring/ -15. topics about the BTRFS filesystem (mount options, supported file attributes and other) | Man Page - ManKier, accessed June 15, 2026, https://www.mankier.com/5/btrfs -16. 6.2. Mounting a btrfs file system | Storage Administration Guide | Red Hat Enterprise Linux, accessed June 15, 2026, https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/storage_administration_guide/btrfs-mount -17. ChangeLog-5.12.3 - The Linux Kernel Archives, accessed June 15, 2026, https://www.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.12.3 -18. Solid state drive - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/Solid_state_drive -19. How to change the default mount options for a specific file system but not a specific disk partition? - LinuxQuestions.org, accessed June 15, 2026, https://www.linuxquestions.org/questions/linux-general-1/how-to-change-the-default-mount-options-for-a-specific-file-system-but-not-a-specific-disk-partition-4175717985/ -20. 216050 – f2fs_gc occupies 100% cpu - Kernel Bugzilla, accessed June 15, 2026, https://bugzilla.kernel.org/show_bug.cgi?id=216050 -21. accessed June 15, 2026, https://www.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.8.6 -22. ChangeLog-4.19.172 - The Linux Kernel Archives, accessed June 15, 2026, https://www.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.19.172 -23. 3.6. Journal (jbd2) — The Linux Kernel documentation, accessed June 15, 2026, https://www.kernel.org/doc/html/latest/filesystems/ext4/journal.html -24. NTFS — The Linux Kernel documentation, accessed June 15, 2026, https://docs.kernel.org/filesystems/ntfs3.html -25. What is the correct equivalent to defaults mount option in the new ntfs? : r/archlinux - Reddit, accessed June 15, 2026, https://www.reddit.com/r/archlinux/comments/1e4m9zd/what_is_the_correct_equivalent_to_defaults_mount/ -26. "dmask" and "fmask" mount options - Ask Ubuntu, accessed June 15, 2026, https://askubuntu.com/questions/429848/dmask-and-fmask-mount-options -27. mount(8) - Linux manual page - man7.org, accessed June 15, 2026, https://man7.org/linux/man-pages/man8/mount.8.html -28. How to Mount exFAT Drives on Ubuntu 24.04 and 22.04 | Linuxize, accessed June 15, 2026, https://linuxize.com/post/how-to-mount-an-exfat-drive-on-ubuntu/ -29. ExFat mount permission - Unix & Linux Stack Exchange, accessed June 15, 2026, https://unix.stackexchange.com/questions/720284/exfat-mount-permission -30. exfat driver documentation missing · Issue #215 - GitHub, accessed June 15, 2026, https://github.com/exfatprogs/exfatprogs/issues/215 -31. ChangeLog-5.11.20 - The Linux Kernel Archives, accessed June 15, 2026, https://www.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.11.20 -32. ISO9660 Filesystem - The Linux Kernel documentation, accessed June 15, 2026, https://docs.kernel.org/filesystems/isofs.html -33. Documentation/filesystems/f2fs.txt - kernel/common - Git at Google - Android GoogleSource, accessed June 15, 2026, https://android.googlesource.com/kernel/common/+/22f837981514e157f8f9737b25ac6d7d90a14006/Documentation/filesystems/f2fs.txt -34. 218471 – F2FS fails to mount rw at boot with "invalid zstd compress level - Kernel Bugzilla, accessed June 15, 2026, https://bugzilla.kernel.org/show_bug.cgi?id=218471 -35. dm-crypt/Device encryption - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/Dm-crypt/Device_encryption -36. dm-crypt/Drive preparation - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/Dm-crypt/Drive_preparation -37. feat(I/O): change default SSD and HDD schedulers to remove system lag · basecamp omarchy · Discussion #3856 - GitHub, accessed June 15, 2026, https://github.com/basecamp/omarchy/discussions/3856 -38. BTRFS on LUKS + no_write_workqueue + no_read_workqueue + allow-discards - Fedora Discussion, accessed June 15, 2026, https://discussion.fedoraproject.org/t/btrfs-on-luks-no-write-workqueue-no-read-workqueue-allow-discards/189349 +Filesystem and Storage Architecture Report for Arch Linux (2026) +Executive Summary for Arch Linux in 2026 +The landscape of Linux storage and filesystem architecture has undergone a paradigm shift leading into June 2026, driven by the maturation of the 7.x kernel series, the ubiquitous adoption of PCIe 5.0 Non-Volatile Memory Express (NVMe) solid-state drives, and the deprecation of legacy user-space storage drivers. For modern Arch Linux deployments, the reliance on Filesystem in Userspace (FUSE) modules—historically utilized to bridge cross-platform interoperability gaps—is officially obsolete.1 Modern infrastructure exclusively leverages in-kernel drivers, notably native ntfs (introduced in 7.1) and native exfat, which eliminate the severe context-switching latency and CPU overhead previously associated with interoperability layers while providing robust, POSIX-compliant translation matrices.3 +Simultaneously, the mechanical realities of storage mediums have bifurcated filesystem optimization strategies. The internal logic of modern flash memory controllers, specifically their sophisticated Flash Translation Layers (FTLs), has rendered many historical Linux filesystem optimizations actively detrimental.5 As storage bottlenecks have migrated from the physical NAND flash or magnetic platters to the kernel's block layer and cryptographic workqueues, legacy recommendations regarding complex block alignment flags, synchronous discard operations, and manual garbage collection must be meticulously audited and, in many cases, purged from automation scripts.6 +This exhaustive report provides a definitive, source-grounded decision matrix for filesystem deployment, cryptographic volume management, and mount automation on the current Arch Linux stack. It delineates the strict boundaries between format-time (mkfs) parameters, decryption-time (cryptsetup) configurations, background daemon (systemd) operations, and runtime (mount) flags. By systematically analyzing Btrfs, ext4, NTFS (kernel module), exFAT, VFAT, and F2FS, this document establishes a highly technical framework for safe defaults, conditional performance enhancements, and deprecated practices, ensuring automated drive management scripts are highly optimized, secure, and fully aligned with current upstream kernel behaviors. +Recent Changes Invalidating Legacy Documentation +The rapid evolution of the Linux Virtual File System (VFS) layer and block device management frequently outpaces community documentation. Implementing stale advice from older forum posts or outdated wiki revisions can precipitate severe performance degradation, premature hardware wear, or catastrophic kernel panics. The following architectural shifts fundamentally invalidate historical storage management paradigms. +The deprecation of FUSE for cross-platform filesystems marks a critical performance milestone. Historically, the ntfs-3g and exfat-fuse packages were mandatory for managing Microsoft-formatted drives. These have been superseded by the ntfs and exfat kernel modules.1 Automation scripts invoking mount.ntfs-3g or utilizing FUSE-specific flags will now experience mounting errors or silent fallback failures, particularly in headless daemon environments.8 The native kernel drivers execute operations directly in ring zero, providing near-native Ext4 throughput speeds on NTFS volumes, but they require a distinct set of permission-synthesizing mount flags to function securely, and the mount command must bypass userspace helpers (via the -i flag) to avoid falling back to FUSE ntfs-3g if it is installed on the system.3 +Within the Btrfs ecosystem, the handling of discarded blocks has been entirely overhauled. The discard=async mount option is now the default kernel behavior for Btrfs on solid-state drives.6 Older documentation universally suggested disabling mount-time discard due to I/O stalling, recommending instead the use of a periodic fstrim.timer via systemd. This advice is no longer applicable to Btrfs; the asynchronous implementation intelligently batches freed extents in memory and issues non-blocking TRIM commands exclusively during device idle periods.6 Furthermore, legacy Btrfs SSD layout optimizations, such as ssd_spread, were engineered for first-generation FTLs that struggled with block wear-leveling. Modern SSD controllers manage wear-leveling internally and opaquely. Forcing legacy layout optimizations on modern NVMe drives actively interferes with the hardware controller, increasing logical fragmentation without providing physical endurance benefits.6 +Cryptographic overhead has also shifted. For high-throughput NVMe drives, the default dm-crypt subsystem behavior introduces measurable latency by offloading cryptographic operations to kernel workqueues. The introduction of the no-read-workqueue and no-write-workqueue flags in /etc/crypttab acknowledges that modern multi-core processors can decrypt data inline faster than the kernel can manage the context switch to a background worker thread. Bypassing these queues massively reduces latency for random I/O operations at the cost of a nominal increase in immediate CPU utilization.7 +Finally, legacy safety mechanisms for removable media have been proven harmful. Older guides recommended the flush mount option for VFAT and exFAT USB flash drives to force immediate synchronous writes, ostensibly preventing data corruption if a user abruptly removed the drive. On modern kernels, this flag forces the flash memory controller to write tiny, highly inefficient blocks continuously, halving write throughput and rapidly exhausting the drive's limited write-erase cycle endurance.11 Modern deployments must rely on the standard kernel page cache and enforce software unmounting, utilizing options like errors=remount-ro rather than synchronous flushing. +Drive-Class Architectural Decision Matrix +The physical attributes and firmware logic of the underlying storage medium dictate the correct parameter usage entirely independently of the filesystem overlaid upon it. Understanding the mechanical realities of the drive class is the prerequisite for selecting the appropriate software flags. +Solid-state drives and NVMe storage rely on NAND flash memory gates, which cannot be overwritten directly; a block must be electronically erased before new data can be written. This process is managed by the drive's FTL, which maps logical operating system blocks to physical flash cells. The primary goal for SSDs is reducing "write amplification"—the phenomenon where writing a small amount of data forces the controller to erase and rewrite a large block of surrounding data. Consequently, features like transparent filesystem compression (which reduces the total payload size) and asynchronous TRIM (which informs the controller which blocks are no longer needed by the OS, allowing it to pre-erase them) are critical for SSD health.5 Conversely, attempting to physically defragment an SSD via filesystem utilities is highly destructive, as it burns write cycles moving data around a medium that possesses zero mechanical seek latency.6 +Rotational Hard Disk Drives (HDDs) operate via a mechanical actuator arm traversing magnetic platters. Their primary performance bottleneck is seek time—the physical milliseconds required to move the read/write head to a specific track. Therefore, HDD optimization focuses entirely on ensuring data is written contiguously. Delayed allocation (delalloc) allows the filesystem to hold data in RAM until a large, continuous chunk of free disk space is found, preventing the fragmentation of large files.12 Furthermore, extending the commit interval of journaling filesystems prevents the mechanical arm from constantly interrupting a long sequential write to snap back and update the filesystem journal.12 Features like TRIM (discard) are physically impossible and irrelevant for magnetic media. +Removable USB flash media and SD cards utilize highly inferior NAND flash compared to internal NVMe drives, lacking DRAM caches and featuring rudimentary FTLs. They are highly susceptible to sudden power loss and rapid wear. The optimization strategy here shifts to minimizing metadata writes (via options like lazytime) and ensuring that cross-platform filesystems (like exFAT or VFAT) are mounted with strict error-handling constraints (errors=remount-ro) to freeze the filesystem the moment corruption is detected, preventing cascaded data loss.13 +Global Drive-Class Recommendations +Drive Class + Baseline Architecture Strategy + Critical Optimization Tweaks + Toxic Operations to Avoid + Internal SSD / NVMe + Rely on asynchronous TRIM (discard=async for Btrfs, hybrid for F2FS) or systemd's fstrim.timer (ext4). Focus on reducing write amplification. + noatime, lazytime. Increase journal commit intervals. Enable transparent compression to reduce flash cell wear. + Defragmentation tools (e.g., autodefrag), synchronous discard, legacy ssd_spread flags. + Rotational HDD + Optimize for continuous sequential read/write operations to prevent actuator arm thrashing and seek latency. + autodefrag (Btrfs only), delalloc (ext4), commit=20. Enable compression to increase logical throughput by packing more data per physical track. + Any form of discard or TRIM. Btrfs nodatacow on small files (causes severe mechanical fragmentation). + External USB / Flash + Maximize cross-operating-system interoperability. Protect against abrupt physical disconnects while minimizing metadata wear. + Synthesize permissions (uid=1000, gid=1000), enforce Windows compliance (windows_names), use errors=remount-ro. + The flush option (destroys throughput and hardware endurance). Synchronous journaling. + Shared Windows Interop + Utilize kernel-native translation modules (ntfs, exfat) to map POSIX standards to Windows metadata logic. + umask=022, iocharset=utf8, prealloc (for large media transfers). + The force flag (corrupts Windows hibernation and fast-startup dirty bits). + File-System-by-File-System Implementation Matrix +The following sections exhaustively define the parameters applicable to modern filesystems, meticulously categorizing them by implementation layer: format-time (mkfs), decryption-time (cryptsetup), background services (systemd), and runtime (mount). +Btrfs (B-Tree Filesystem) +Btrfs is an advanced Copy-on-Write (CoW) filesystem engineered for fault tolerance, atomic snapshotting, and robust subvolume management. Unlike traditional filesystems that overwrite data in place, Btrfs writes modifications to new blocks and updates the metadata pointers, ensuring that a crash during a write operation never corrupts the original data. +A critical architectural constraint of Btrfs is the scope of its mount options. The vast majority of Btrfs mount options apply globally to the entire physical filesystem, not to individual subvolumes. The Linux VFS layer parses the mount options provided when the first subvolume of a Btrfs partition is mounted; subsequent subvolume mounts from the same partition will silently inherit these global options, ignoring conflicting flags provided in their specific mount commands.15 Therefore, it is architecturally impossible to set compress=zstd on a /home subvolume and nodatacow on a /var subvolume if they reside on the same backing block device.6 Furthermore, option ordering matters during evaluation; the system processes options from left to right, and the final occurrence of conflicting options takes precedence.15 +Btrfs Configuration Parameters + + +Option Name + Implementation Layer + Classification + Explanation & Mechanical Behavior + Version / Confidence Note + ssd / nossd + Mount + Auto-detected Default + Modifies block allocation heuristics by removing rotational seek penalties. Automatically triggered if the kernel detects a non-rotational medium. Do not specify manually.6 + Standard behavior. High confidence. + discard=async + Mount + Safe Default + Gathers freed extents in a memory queue and dispatches non-blocking TRIM commands to the SSD controller during idle I/O periods.6 + Default since Kernel 6.2+. Replaces fstrim.timer. + space_cache=v2 + Mount + Safe Default + Replaces the legacy free-space tracking mechanism with a highly optimized, persistent B-tree, drastically reducing mount times and CPU overhead during block allocation.16 + Default on modern Arch. v1 is heavily deprecated. + compress=zstd:3 + Mount + Performance Tweak + Transparently compresses data payloads using the Zstandard algorithm before writing to disk. Reduces SSD write amplification and increases effective HDD throughput. Level 3 is the optimal balance of speed and ratio.6 + Supported since Kernel 5.1+. Automatically disables nodatacow. + compress-force=zstd:3 + Mount + Conditional Tweak + Bypasses the filesystem's early heuristic checks (which abort compression if the first few bytes appear incompressible) and forces a compression attempt on the entire payload.6 + Use only for highly compressible datasets (e.g., text, logs). Wastes CPU on pre-compressed video files. + nodatacow + Mount + Conditional Tweak + Disables Copy-on-Write semantics. Data is overwritten in-place. Implicitly disables both data checksumming (nodatasum) and transparent compression.6 + Mandatory for VM images and heavy databases (PostgreSQL/SQLite) to prevent catastrophic internal fragmentation.12 + autodefrag + Mount + Rotational Media Only + Scans for small, random writes and queues them for background physical defragmentation into contiguous blocks.12 + Highly toxic to SSDs. Accelerates flash cell wear for zero mechanical benefit. Mandatory for HDDs.6 + subvol=/path + Mount + Generic Mount Option + Instructs the VFS layer to mount a specific subvolume path as the root of the designated mount point, overriding the partition's default subvolume ID.6 + Overrides subvolid if both are specified and conflict. + Btrfs Baseline Recommendations +* 1. SSD/NVMe Baseline: discard=async,space_cache=v2,compress=zstd:3,noatime. (Relies on background TRIM and compression to extend flash life). +* 2. Rotational HDD Baseline: space_cache=v2,compress=zstd:3,noatime,autodefrag. (Relies on defragmentation to reduce seek times; compression packs more data per magnetic track). +* 3. Removable USB Media: Not recommended. Btrfs metadata overhead and CoW architecture are too heavy for low-tier flash controllers without dedicated DRAM caches. +* 4. Shared Windows Interop: Incompatible. Windows requires third-party, highly unstable drivers to read Btrfs. +* 5. Encrypted Drives: Inherits the underlying SSD/HDD baseline. Btrfs is unaware of the lower dm-crypt layer. +* 6. Options to Avoid: discard=sync, ssd_spread (interferes with modern FTLs), space_cache=v1. +Ext4 (Fourth Extended Filesystem) +Ext4 remains the industry gold standard for traditional, high-performance, non-CoW Linux filesystems. It utilizes a robust journaling architecture to ensure metadata consistency in the event of power loss, logging intended changes to a dedicated disk area before committing them to the primary filesystem structure. Because it does not utilize Copy-on-Write, it is highly resilient against the severe fragmentation issues that plague Btrfs when hosting virtual machine images or active databases. +Unlike Btrfs, Ext4's native discard mount option historically operated synchronously. When a file was deleted, the kernel would immediately issue a TRIM command and halt the I/O queue until the SSD controller confirmed the block was erased. On heavy workloads, this introduces massive latency spikes. Therefore, the modern architectural standard for Ext4 completely abandons the discard mount flag in favor of systemd's scheduled fstrim.timer, which handles garbage collection in bulk during off-peak hours.17 +Ext4 Configuration Parameters + + +Option Name + Implementation Layer + Classification + Explanation & Mechanical Behavior + Version / Confidence Note + noatime + Mount + Safe Default + Eliminates the legacy POSIX requirement to update a file's access timestamp (i_atime) upon every read operation. Prevents the "write-after-every-read" performance penalty.12 + Replaces the kernel default relatime. Safe for all modern systems.19 + lazytime + Mount + Performance Tweak + Caches updates to access, modification, and creation timestamps purely in RAM. The kernel flushes these to the physical disk only when the inode undergoes other metadata changes or during unmount.21 + Excellent for reducing metadata wear on flash drives and reducing seek activity on HDDs. + delalloc + Mount + Safe Default + Delayed allocation. The kernel accumulates file data in memory caches, analyzing the total size before searching the physical disk for a single, contiguous block of free space.12 + Default behavior. Drastically minimizes fragmentation for large file writes. + commit=20 + Mount + Performance Tweak + Dictates the frequency (in seconds) at which the kernel flushes the in-memory journal to the physical disk. Ext4 defaults to 5 seconds; 20 seconds drastically reduces write operations.12 + Highly recommended for reducing SSD wear. Risk: A sudden power loss guarantees up to 20 seconds of data loss. + fstrim.timer + Systemd + Scheduled Service + A background systemd daemon that issues a batched TRIM command across the entire filesystem block structure, typically executing weekly.17 + Preferred over mount-time discard for Ext4 to prevent synchronous I/O queue stalling. + Ext4 Baseline Recommendations +* 1. SSD/NVMe Baseline: noatime,lazytime,delalloc,commit=20. (Relies on fstrim.timer for garbage collection. Maximizes throughput by delaying metadata writes). +* 2. Rotational HDD Baseline: noatime,lazytime,delalloc,commit=20. (Extending the commit interval prevents the actuator arm from constantly seeking back to the journal partition). +* 3. Removable USB Media: noatime,lazytime,commit=60. (While Ext4 is not ideal for cross-platform USBs, extending the commit to 60 seconds drastically saves cheap flash cells from journal burnout). +* 4. Shared Windows Interop: Incompatible without third-party Windows software. +* 5. Encrypted Drives: Standard baselines apply. Ext4's lack of CoW makes it the highest-performing filesystem inside a LUKS container for heavy database workloads.12 +* 6. Options to Avoid: discard (causes synchronous I/O stalling), data=journal (forces all file data through the journal, halving write speed).23 +NTFS (Native NTFS Kernel Module in Linux 7.1+) +Introduced in kernel 7.1, the rewritten native kernel ntfs module completely replaces the older ntfs3 Paragon driver and the legacy userspace ntfs-3g driver.3 NTFS is the proprietary filesystem of Microsoft Windows. Because the NTFS metadata structure possesses no concept of Linux user IDs, group IDs, or POSIX execution bits, the Linux VFS must synthesize these permissions mathematically at the exact moment the drive is mounted. Failure to explicitly define these translation parameters results in the entire drive defaulting to root ownership, rendering it completely read-only for standard users.25 +Furthermore, Windows enforces strict file naming conventions that Linux does not share. Linux allows almost any character except a forward slash and a null byte in a filename. If a Linux user creates a file named report?.txt on an NTFS drive, Windows will view the NTFS Master File Table (MFT) as corrupted and demand a disk check upon reboot. Modern ntfs parameters must safeguard against this, and the mount command must bypass userspace helpers (using the -i flag) to prevent calling legacy ntfs-3g helpers.1 +NTFS Configuration Parameters + + +Option Name + Implementation Layer + Classification + Explanation & Mechanical Behavior + Version / Confidence Note + uid=, gid= + Mount + Mandatory + Explicitly defines the integer User ID and Group ID that will be synthesized as the owner of all files and directories on the NTFS volume.3 + Typically set to uid=1000,gid=1000 for the primary system user.25 + umask=, dmask=, fmask= + Mount + Mandatory + Establishes the inverse permission bitmask. dmask applies to directories, fmask applies to files. A umask=022 yields 755 permissions for directories and 644 for files.3 + Essential for preventing the volume from becoming world-writable (777). + windows_names + Mount + Compatibility Tweak + Enforces strict Windows naming restrictions within the Linux VFS, actively blocking the creation of files containing characters like *, ?, <, >, or reserved DOS names like CON.1 + Prevents MFT index corruption when the drive is returned to a Windows host.12 + iocharset=utf8 + Mount + Compatibility Tweak + Instructs the driver to translate wide-character NTFS path strings into standard UTF-8 for the Linux terminal.3 + Safe default. Prevents encoding errors on complex filenames.27 + prealloc + Mount + Performance Tweak + Instructs the kernel to aggressively preallocate contiguous disk sectors when a file's size is detected as increasing during a write operation.3 + Highly recommended to combat severe fragmentation during large media downloads or transfers.3 + force + Mount + Highly Toxic + Overrides the kernel's safety lock and mounts the volume read-write even if the NTFS "dirty bit" is flagged.3 + Never use. Bypassing the dirty bit on a hibernated Windows drive guarantees catastrophic filesystem corruption.24 + NTFS Baseline Recommendations +* 1. SSD/NVMe Baseline: Native Linux filesystems are vastly superior. If forced to use NTFS internally, use: uid=1000,gid=1000,umask=022,noatime,prealloc (making sure to mount with -i to bypass userspace helpers). +* 2. Rotational HDD Baseline: uid=1000,gid=1000,umask=022,noatime,prealloc. (Preallocation is vital to prevent physical fragmentation). +* 3. Removable USB Media: exFAT is preferred for flash media, but NTFS works with standard parameters. +* 4. Shared Windows Interop Baseline: uid=1000,gid=1000,umask=022,windows_names,iocharset=utf8,prealloc. (Ensures perfect cross-platform read/write compliance without corrupting the MFT).12 +* 5. Encrypted Drives: NTFS inside LUKS is possible but highly niche. Parameters remain identical. +* 6. Options to Avoid: force (corrupts hibernated drives), ntfs-3g (legacy FUSE driver, high CPU overhead), ntfs3 (legacy Paragon driver). +exFAT (Extensible File Allocation Table) +exFAT is the modern industry standard for high-capacity external USB drives and SDXC cards, designed explicitly by Microsoft to replace FAT32 without inheriting the immense metadata overhead of NTFS. Supported natively in the Linux kernel, it is the optimal choice for cross-platform flash storage.4 Like NTFS, exFAT lacks native POSIX ownership concepts and requires mathematical permission synthesis at mount time. +Because exFAT is heavily utilized on external, removable flash drives—which are physically prone to being unexpectedly unplugged or suffering from cheap, degrading flash memory—the kernel must be instructed on how to handle sudden physical layer corruption gracefully. +exFAT Configuration Parameters + + +Option Name + Implementation Layer + Classification + Explanation & Mechanical Behavior + Version / Confidence Note + uid=, gid=, umask= + Mount + Mandatory + Performs the identical permission synthesis operations as the NTFS module, ensuring the mounted volume is accessible to the current Linux user.29 + Use uid=1000,gid=1000,dmask=022,fmask=133 to grant full directory traversal without making files executable. + errors=remount-ro + Mount + Safety Tweak + Instructs the kernel's block layer to instantly lock the volume into read-only mode the millisecond filesystem corruption or a physical read/write error is detected.14 + Critical safety mechanism for degraded USB flash drives, preventing cascaded data loss. + discard + Mount + Conditional + Passes TRIM commands through the exFAT driver to the underlying flash medium.17 + Only effective if the USB enclosure firmware explicitly supports UASP (USB Attached SCSI Protocol) and TRIM pass-through. Otherwise, it throws errors. + exFAT Baseline Recommendations +* 1. SSD/NVMe Baseline: Do not use exFAT for internal OS drives. It lacks journaling and is highly fragile under parallel I/O loads. +* 2. Rotational HDD Baseline: Do not use exFAT for internal mechanical drives. +* 3. Removable USB Media Baseline: uid=1000,gid=1000,dmask=022,fmask=133,errors=remount-ro,iocharset=utf8. (The absolute standard for USB thumb drives over 32GB). +* 4. Shared Windows Interop: See Removable USB Media Baseline. +* 5. Encrypted Drives: Incompatible. Removable drives needing encryption should use LUKS with a native Linux FS, sacrificing Windows interop. +* 6. Options to Avoid: Attempting to mount via the deprecated exfat-fuse user-space utility.2 +VFAT / FAT32 +VFAT is a legacy filesystem strictly bounded by a maximum file size of 4GB. In modern Arch Linux deployments, its exclusive purpose is formatting the EFI System Partition (ESP) required by UEFI firmware for booting the operating system, or formatting very small (<32GB) legacy USB sticks.13 +A deeply entrenched piece of legacy advice for VFAT was the use of the flush mount option for USB flash drives. This option was historically meant to protect users who yanked USB drives out without safely unmounting them by forcing the kernel to synchronize data to the flash drive upon every single write syscall. On modern kernels and modern flash drives, the flush option forces the flash memory controller to write tiny, unaligned metadata blocks continuously. This specific interaction destroys the drive's endurance and demonstrably cuts write throughput in half compared to relying on the standard kernel page cache.11 +VFAT Configuration Parameters + + +Option Name + Implementation Layer + Classification + Explanation & Mechanical Behavior + Version / Confidence Note + shortname=mixed + Mount + Compatibility Tweak + Dictates the algorithm the kernel uses to generate and display legacy 8.3 character DOS filenames.13 + Safe default. Replaces the deprecated nocase flag.13 + utf8 + Mount + Compatibility Tweak + Encodes Unicode names in UTF-8 format for proper display in the Linux terminal.32 + Standard requirement for modern locales. + flush + Mount + Highly Toxic + Forces immediate synchronization of data and metadata to the physical flash cells upon every VFS write operation.11 + Never use. Devastates flash memory throughput and physical endurance.11 Rely on proper software unmounting. + VFAT Baseline Recommendations +* 1. SSD/NVMe Baseline: Only utilized for the /boot/efi partition. Use fmask=0137,dmask=0027 to lock down bootloader security. +* 2. Removable USB Media: uid=1000,gid=1000,shortname=mixed,utf8,errors=remount-ro. (Only use for drives <32GB; otherwise, utilize exFAT). +* 3. Options to Avoid: flush (destroys drive health and speed). +F2FS (Flash-Friendly File System) +F2FS is an advanced, highly specialized Log-Structured File System engineered from the ground up for NAND-based flash memory (NVMe, SATA SSDs, eMMC, and SD cards) equipped with an internal Flash Translation Layer (FTL). Unlike traditional filesystems that overwrite data in place, F2FS continually appends new data to the end of a log, turning random writes into fast sequential writes and significantly reducing the write amplification that destroys flash cells over time.5 +Because it continuously appends data, F2FS requires a robust Garbage Collection (GC) mechanism to reclaim space from old, invalidated data blocks. Modern F2FS implementations have introduced Asynchronous Threaded Garbage Collection (atgc), which moves this intense consolidation process into a non-blocking background thread. However, F2FS operates uniquely regarding compression: unlike Btrfs, F2FS compression does not immediately expose the saved space to the user. Instead, it reserves the logical blocks to strictly minimize the amount of physical data pushed to the flash cells, maximizing hardware lifespan over perceived capacity.5 +F2FS Configuration Parameters + + +Option Name + Implementation Layer + Classification + Explanation & Mechanical Behavior + Version / Confidence Note + compression + mkfs (Format) + Mandatory Prerequisite + Compression must be physically enabled at the block level during filesystem creation (mkfs.f2fs -O compression) before it can be utilized by mount flags.5 + Cannot be enabled retroactively without reformatting. + compress_algorithm=zstd:6 + Mount + Performance Tweak + Instructs the VFS to utilize the Zstandard algorithm at compression level 6. This provides a highly favorable ratio, drastically reducing physical wear on the NAND gates.5 + Only operates on files flagged via chattr +c or globally via compress_extension=*. + compress_chksum + Mount + Safety Tweak + Cryptographically hashes and verifies compressed blocks during read operations to actively prevent silent data corruption.5 + Essential safety net; compression makes bit-rot highly destructive. + atgc + Mount / Kernel + Performance Tweak + Enables the superior Asynchronous Threaded Garbage Collector. Warning: If F2FS is the root partition (/), placing this in /etc/fstab will cause a systemd remount failure. It must be passed as a bootloader kernel parameter (rootflags=atgc).5 + Resolves severe blocking I/O spikes associated with legacy synchronous F2FS garbage collection. + gc_merge + Mount + Performance Tweak + Allows the kernel to merge foreground garbage collection tasks, executing them asynchronously.5 + High-performance complement to atgc. + lazytime + Mount + Safe Default + Defers file timestamp updates to RAM. Critical for log-structured filesystems to prevent generating endless tiny log appends just to record read access times.5 + Essential for F2FS endurance. + nodiscard + Mount + Conditional + F2FS utilizes a highly intelligent hybrid asynchronous TRIM by default. If a user strictly prefers utilizing systemd's periodic fstrim.timer, they must explicitly pass nodiscard to stop F2FS from competing with the timer.5 + Rely on the F2FS default unless specifically troubleshooting firmware TRIM bugs. + F2FS Baseline Recommendations +* 1. SSD/NVMe Baseline: compress_algorithm=zstd:6,compress_chksum,atgc,gc_merge,lazytime. (Requires rootflags=atgc in the bootloader if used for the root filesystem). +* 2. Rotational HDD Baseline: Incompatible. Log-structured filesystems cause extreme mechanical actuator thrashing on magnetic drives. +* 3. Removable USB Media: lazytime,atgc,gc_merge. (Excellent for extending the life of SD cards and USB drives, provided they are only used on Linux machines). +* 4. Shared Windows Interop: Incompatible. Windows cannot read F2FS. +* 5. Encrypted Drives: Standard baselines apply. F2FS works excellently under LUKS to reduce cryptographic write amplification. +* 6. Options to Avoid: discard=sync (stalls the log appender). +Encrypted Volumes (LUKS2 / dm-crypt) +The Linux Unified Key Setup (LUKS) operates as a block-device translation layer (dm-crypt), situated between the raw physical hardware and the filesystem (VFS) layer. Because the encryption layer wraps the raw blocks, it dictates a strict operational hierarchy: cryptographic parameters are entirely managed by cryptsetup during formatting and by /etc/crypttab during the boot unlock phase, before the filesystem is mounted by fstab.7 +A monumental bottleneck in modern Linux storage involves the intersection of dm-crypt and PCIe 4.0/5.0 NVMe drives. Historically, dm-crypt utilized kernel workqueues to process cryptographic decryption. A CPU core would request data, and the kernel would offload the decryption math to a background worker thread. On mechanical drives or SATA SSDs, the drive's latency was so high that the CPU context-switch time was negligible. However, modern NVMe drives operate at single-digit microsecond latencies. The kernel's context switch to the workqueue now takes longer than the drive takes to fetch the data, severely bottlenecking random I/O performance.7 +Cryptographic Parameter Matrix + + +Option Name + Implementation Layer + Classification + Explanation & Mechanical Behavior + Version / Confidence Note + --sector-size 4096 + mkfs (Format) + Performance Tweak + Passed to cryptsetup luksFormat. The legacy dm-crypt default was 512 bytes. Modern NVMe drives and high-capacity HDDs utilize 4K native physical sectors. Forcing 4096 bytes aligns the cryptographic payload perfectly with the physical hardware gates, eliminating the massive read-modify-write performance penalty.35 + Cannot be altered without totally destroying and recreating the LUKS container. + no-read-workqueue + crypttab (Unlock) + Performance Tweak + Bypasses the kernel's cryptographic read workqueues. Forces the decryption mathematics to execute synchronously inline on the exact CPU core that requested the I/O operation.7 + Mandatory for NVMe drives. Can increase random I/O speeds by up to 30%. Adds slight CPU overhead.10 + no-write-workqueue + crypttab (Unlock) + Performance Tweak + Identical to above, but applies to the write path, enforcing inline encryption before dispatching to the NVMe controller.7 + Apply together with no-read-workqueue in /etc/crypttab. + discard / --allow-discards + crypttab (Unlock) + Conditional Tradeoff + Instructs the dm-crypt block layer to pierce the encryption veil and pass TRIM commands from the upper filesystem down to the physical SSD controller.7 + Security Tradeoff: Passing TRIM allows a forensic attacker to see exactly which blocks are physically empty, breaking plausible deniability and mapping filesystem usage. Performance Tradeoff: Blocking TRIM causes severe write amplification on the SSD over time. For non-state-secret hardware, the physical performance preservation outweighs the metadata security leak.7 + The "Do Not Use By Default" List +The following VFS flags and operational strategies persist in outdated wikis, automated scripts, and community lore. They pose active, quantifiable threats to system performance, hardware longevity, or data integrity on the current Arch Linux stack. +1. discard=sync (or bare discard on ext4): Forces the kernel to block the entire I/O queue while waiting for the SSD controller to physically erase a flash block. This results in severe system stalling during large file deletions. Rely exclusively on Btrfs's discard=async or systemd's scheduled fstrim.timer.6 +2. flush on VFAT/FAT32: Ostensibly a safety feature for USB drives, this flag forces every tiny metadata update (such as updating an access time) to immediately commit to the physical flash cells. It destroys USB drive throughput, cutting speeds by 50% or more, and rapidly burns through the drive's limited write-erase endurance.11 +3. force on NTFS: Ignores the NTFS volume's internal dirty bit. If a Windows partition is placed into hibernation or utilizes "Fast Startup," its metadata is locked. Forcing a read-write mount from Linux will brutally corrupt the Windows Master File Table (MFT).24 +4. space_cache=v1 on Btrfs: An obsolete, highly fragmented caching mechanism. Ensure all automation scripts specify space_cache=v2.16 +5. autodefrag on SSDs/NVMes: Forces the Btrfs filesystem to continuously rewrite data blocks into contiguous alignments. Because solid-state drives possess zero mechanical read heads, contiguous logical alignment provides zero physical read-speed benefit. This flag only serves to continuously burn through the limited write-lifespan of the NAND flash gates.6 +6. Mixing nodatacow and compress: On Btrfs architectures, transparent compression strictly requires Copy-on-Write logic to function. Passing nodatacow implicitly and silently disables all compression and checksumming algorithms.6 Attempting to mix these flags in a script indicates a fundamental misunderstanding of the filesystem's topology. +Mount Automation Script Matrix (TOML Configurations) +The following matrices synthesize this exhaustive research into precise, parseable TOML blocks specifically engineered to be ingested by automation scripts (such as a Python drive_manager.py). These parameters translate directly into highly optimized kernel VFS configurations.12 +1. The NVMe System / Browser Partition (Btrfs) +High-speed flash optimization. Designed for maximum throughput, relying on modern SSD FTLs and inline decryption. + + + + + + +Ini, TOML +[drives.nvme_system] +type = "PROTECTED" +mountpoint = "/mnt/system" +outer_uuid = "0a52e1bb-4fa0-4138-a150-f59467903e22" +inner_uuid = "1adeb61a-0605-4bbc-8178-bb81fe1fca09" +hint = "system_key" +fstype = "btrfs" +mount_options = +# CRITICAL: Ensure /etc/crypttab includes 'no-read-workqueue,no-write-workqueue,discard' +# for the outer_uuid block device to eliminate context-switch latency on NVMe hardware. + +2. The Internal Media Storage (Ext4) +Mass storage optimization. Focused on reducing metadata writes and preventing fragmentation of massive sequential files. + + + + + + +Ini, TOML +[drives.media_ssd] +type = "PROTECTED" +mountpoint = "/mnt/media" +outer_uuid = "98353f6a-b21b-4966-9f57-948678bde66d" +inner_uuid = "a7230e67-34e8-4cd2-981d-ea02d1253539" +hint = "media_key" +fstype = "ext4" +mount_options = +# NOTE: Relies exclusively on systemd's fstrim.timer for garbage collection. + +3. The Rotational Hard Disk Drive Archive (Btrfs) +Mechanical drive optimization. Targeting the absolute mitigation of physical actuator arm seek latency. + + + + + + +Ini, TOML +[drives.rotational_archive] +type = "PROTECTED" +mountpoint = "/mnt/archive" +outer_uuid = "953a147e-a346-4fea-91f4-a81ec97fa56a" +inner_uuid = "46798d3b-cda7-4031-818f-37a06abbeb37" +hint = "archive_key" +fstype = "btrfs" +mount_options = + +4. Shared Windows / Interoperability Drive (NTFS) +Cross-platform safety, synthesized POSIX compliance, utilizing kernel-native rendering. + + + + + + +Ini, TOML +[drives.windows_shared] +type = "SIMPLE" +mountpoint = "/mnt/windows" +outer_uuid = "848A215E8A214E4C" +fstype = "ntfs" # Modern in-kernel module; bypassed FUSE via -i mount flag +mount_options = + +5. Flash-Native Removable Storage (F2FS) +Maximum NAND endurance architecture for SD Cards and unencrypted USB Flash Drives. + + + + + + +Ini, TOML +[drives.usb_flash] +type = "SIMPLE" +mountpoint = "/mnt/usb" +outer_uuid = "C4A2B1D3E5" +fstype = "f2fs" +mount_options = +# NOTE: If utilizing F2FS on the primary boot drive, ensure 'rootflags=atgc' +# is present in the bootloader kernel parameters to prevent systemd remount failures. + +Works cited +1. [HowTo] Mount NTFS correctly under Linux - Tutorials, accessed June 15, 2026, https://forum.manjaro.org/t/howto-mount-ntfs-correctly-under-linux/177221 +2. Kernel-mounted vs FUSE-mounted exfat filesystem - Unix & Linux Stack Exchange, accessed June 15, 2026, https://unix.stackexchange.com/questions/761324/kernel-mounted-vs-fuse-mounted-exfat-filesystem +3. NTFS — The Linux Kernel documentation, accessed June 15, 2026, https://www.kernel.org/doc/html/v6.1/filesystems/ntfs3.html +4. How to enable exFAT for Ubuntu 20.04, accessed June 15, 2026, https://askubuntu.com/questions/1234755/how-to-enable-exfat-for-ubuntu-20-04 +5. F2FS - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/F2FS +6. BTRFS SPECIFIC MOUNT OPTIONS — BTRFS documentation, accessed June 15, 2026, https://btrfs.readthedocs.io/en/latest/ch-mount-options.html +7. dm-crypt/Specialties - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/Dm-crypt/Specialties +8. udisks - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/Udisks +9. NTFS — The Linux Kernel documentation, accessed June 15, 2026, https://www.kernel.org/doc/html/v6.2/filesystems/ntfs3.html +10. Disable read/write workqueue for Ubuntu Full-Disk-Encryption, accessed June 15, 2026, https://unix.stackexchange.com/questions/724104/disable-read-write-workqueue-for-ubuntu-full-disk-encryption +11. 198605 – Mounting vfat fs from usb flash drives with "flush" option causes slow write performance - Kernel Bugzilla, accessed June 15, 2026, https://bugzilla.kernel.org/show_bug.cgi?id=198605 +12. drives.toml +13. VFAT - The Linux Kernel documentation, accessed June 15, 2026, https://docs.kernel.org/filesystems/vfat.html +14. How to mount an exFAT external drive , ensuring user permissions, without using /etc/fstab ? : r/linuxquestions - Reddit, accessed June 15, 2026, https://www.reddit.com/r/linuxquestions/comments/1ksf730/how_to_mount_an_exfat_external_drive_ensuring/ +15. topics about the BTRFS filesystem (mount options, supported file attributes and other) | Man Page - ManKier, accessed June 15, 2026, https://www.mankier.com/5/btrfs +16. 6.2. Mounting a btrfs file system | Storage Administration Guide | Red Hat Enterprise Linux, accessed June 15, 2026, https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/storage_administration_guide/btrfs-mount +17. ChangeLog-5.12.3 - The Linux Kernel Archives, accessed June 15, 2026, https://www.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.12.3 +18. Solid state drive - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/Solid_state_drive +19. How to change the default mount options for a specific file system but not a specific disk partition? - LinuxQuestions.org, accessed June 15, 2026, https://www.linuxquestions.org/questions/linux-general-1/how-to-change-the-default-mount-options-for-a-specific-file-system-but-not-a-specific-disk-partition-4175717985/ +20. 216050 – f2fs_gc occupies 100% cpu - Kernel Bugzilla, accessed June 15, 2026, https://bugzilla.kernel.org/show_bug.cgi?id=216050 +21. accessed June 15, 2026, https://www.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.8.6 +22. ChangeLog-4.19.172 - The Linux Kernel Archives, accessed June 15, 2026, https://www.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.19.172 +23. 3.6. Journal (jbd2) — The Linux Kernel documentation, accessed June 15, 2026, https://www.kernel.org/doc/html/latest/filesystems/ext4/journal.html +24. NTFS — The Linux Kernel documentation, accessed June 15, 2026, https://docs.kernel.org/filesystems/ntfs3.html +25. What is the correct equivalent to defaults mount option in the new ntfs? : r/archlinux - Reddit, accessed June 15, 2026, https://www.reddit.com/r/archlinux/comments/1e4m9zd/what_is_the_correct_equivalent_to_defaults_mount/ +26. "dmask" and "fmask" mount options - Ask Ubuntu, accessed June 15, 2026, https://askubuntu.com/questions/429848/dmask-and-fmask-mount-options +27. mount(8) - Linux manual page - man7.org, accessed June 15, 2026, https://man7.org/linux/man-pages/man8/mount.8.html +28. How to Mount exFAT Drives on Ubuntu 24.04 and 22.04 | Linuxize, accessed June 15, 2026, https://linuxize.com/post/how-to-mount-an-exfat-drive-on-ubuntu/ +29. ExFat mount permission - Unix & Linux Stack Exchange, accessed June 15, 2026, https://unix.stackexchange.com/questions/720284/exfat-mount-permission +30. exfat driver documentation missing · Issue #215 - GitHub, accessed June 15, 2026, https://github.com/exfatprogs/exfatprogs/issues/215 +31. ChangeLog-5.11.20 - The Linux Kernel Archives, accessed June 15, 2026, https://www.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.11.20 +32. ISO9660 Filesystem - The Linux Kernel documentation, accessed June 15, 2026, https://docs.kernel.org/filesystems/isofs.html +33. Documentation/filesystems/f2fs.txt - kernel/common - Git at Google - Android GoogleSource, accessed June 15, 2026, https://android.googlesource.com/kernel/common/+/22f837981514e157f8f9737b25ac6d7d90a14006/Documentation/filesystems/f2fs.txt +34. 218471 – F2FS fails to mount rw at boot with "invalid zstd compress level - Kernel Bugzilla, accessed June 15, 2026, https://bugzilla.kernel.org/show_bug.cgi?id=218471 +35. dm-crypt/Device encryption - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/Dm-crypt/Device_encryption +36. dm-crypt/Drive preparation - ArchWiki, accessed June 15, 2026, https://wiki.archlinux.org/title/Dm-crypt/Drive_preparation +37. feat(I/O): change default SSD and HDD schedulers to remove system lag · basecamp omarchy · Discussion #3856 - GitHub, accessed June 15, 2026, https://github.com/basecamp/omarchy/discussions/3856 +38. BTRFS on LUKS + no_write_workqueue + no_read_workqueue + allow-discards - Fedora Discussion, accessed June 15, 2026, https://discussion.fedoraproject.org/t/btrfs-on-luks-no-write-workqueue-no-read-workqueue-allow-discards/189349 diff --git a/user_scripts/firefox/Firefox RAM Optimization on Arch.txt b/user_scripts/firefox/Firefox RAM Optimization on Arch.txt index e0ba55e90..bf344de46 100644 --- a/user_scripts/firefox/Firefox RAM Optimization on Arch.txt +++ b/user_scripts/firefox/Firefox RAM Optimization on Arch.txt @@ -1,268 +1,268 @@ -Advanced Firefox 152 Performance Optimization on Arch Linux and Hyprland: Maximizing Volatile Memory Utilization -Introduction to Modern Browser Optimization on High-Performance Architectures -In the contemporary landscape of high-performance computing, the traditional bottlenecks of web browsing—network latency and graphical rendering throughput—have been largely superseded by local resource mismanagement. On a bleeding-edge system running Arch Linux (specifically Kernel 7.1.0), the Hyprland Wayland compositor, and Mozilla Firefox 152.0.2, paired with 64 Gigabytes of DDR5 RAM, the default configuration of any web browser represents a severe underutilization of available hardware. Standard browser architectures are conservatively engineered to operate within the constrained parameters of 8GB to 16GB memory footprints1. Consequently, they aggressively page out memory to disk, artificially limit concurrent processing, and rely on legacy disk-caching mechanisms that waste the immense bandwidth provided by DDR5 volatile memory2. -The optimization of Firefox 152 on such an architecture requires a fundamental paradigm shift: moving from a disk-bound input/output (I/O) model to a fully memory-bound execution environment. By leveraging Linux kernel features such as tmpfs, fuse-overlayfs, and direct hardware integration via the Video Acceleration API (VA-API) and Direct Media Access Buffer (DMA-BUF), it is possible to entirely eliminate solid-state drive (SSD) latency from the browser's critical path4. Furthermore, the immense 64GB RAM capacity allows for the unthrottling of Firefox’s Electrolysis (e10s) and Fission (Site Isolation) architectures, dedicating discrete operating system-level processes to every individual web origin6. -This comprehensive report provides an exhaustive, critical analysis of the absolute latest methodologies to force Firefox 152 to consume as much volatile memory as necessary to achieve instantaneous responsiveness. The analysis is tailored exclusively for a pure Wayland environment on Arch Linux, ensuring that no legacy X11 or deprecated methodologies are utilized. -Re-architecting Cache Topologies: Eliminating Disk I/O -Every object loaded by Firefox—HTML payloads, JavaScript bundles, WebAssembly modules, and media assets—is cached to prevent redundant network requests. By default, Firefox maintains a dual-cache hierarchy: a high-speed memory cache and a persistent disk cache2. On a system equipped with 64GB of DDR5 RAM, writing temporary web assets to an NVMe SSD is an architectural inefficiency that introduces micro-stutters during concurrent heavy workloads (e.g., rendering dozens of Document Object Models simultaneously)1. -To force Firefox to utilize RAM for all caching operations, two distinct methodologies can be deployed. The first relies on Firefox's native internal memory allocator, while the second leverages the Linux kernel's tmpfs virtual filesystem. -Native Memory Cache Override -The most direct approach to stopping disk I/O is to disable Firefox's disk cache entirely and force all caching into the application's allocated memory space. Through the about:config interface, the native disk cache must be disabled, and the memory cache must be confirmed as active2. -However, a critical scaling issue exists within Firefox's internal logic. By default, the memory cache capacity is determined dynamically. The internal formula used by Firefox to calculate this dynamic limit is: - - -This calculation is based on an archaic table designed for systems with 8GB of system memory or less2. On a 64GB system, this formula asymptotes prematurely, allocating a trivially small amount of RAM (often less than 50MB) to the cache. Therefore, relying on the automatic size selection will starve the browser of cache space. -To resolve this, the capacity must be manually defined. For a 64GB system, allocating 4GB of RAM specifically for internal web caching is optimal. - - -Preference Name - Data Type - Target Value - Mechanism of Action - browser.cache.disk.enable - Boolean - false - Disables disk-based caching, halting SSD write wear for web assets and preventing I/O latency2. - browser.cache.memory.enable - Boolean - true - Forces the browser to retain cached objects entirely in volatile memory2. - browser.cache.memory.capacity - Integer - 4194304 - Allocates exactly 4,194,304 KB (4 GB) of RAM to the internal cache, bypassing the deprecated legacy dynamic scaling algorithm2. - browser.cache.disk.smart_size.enabled - Boolean - false - Prevents the browser from attempting to dynamically resize the disabled disk cache10. - browser.cache.disk_cache_ssl - Boolean - false - Ensures encrypted HTTPS payloads are not forced to the disk cache independently of the primary cache directive10. - browser.cache.offline.enable - Boolean - false - Disables offline caching mechanics which default to disk writing10. - The primary drawback of the native memory cache is that it is entirely ephemeral. In the event of a browser crash or a system reboot, the cache is destroyed, necessitating the re-download of all assets upon subsequent visits2. -Kernel-Level Volatile Caching (tmpfs) -An alternative to the native memory override—and one that offers superior integration with the Linux kernel's page cache and survives browser restarts—is to leave the disk cache enabled within Firefox, but forcefully redirect the read/write operations to a RAM-backed filesystem (tmpfs). -In modern Arch Linux environments managed by systemd, a user-specific tmpfs is automatically mounted at /run/user/ (typically /run/user/1000)5. This directory exists entirely in RAM. The size of this tmpfs is governed by the RuntimeDirectorySize directive in /etc/systemd/logind.conf5. By default, systemd caps this directory at 10% of physical memory (6.4GB on a 64GB system), which provides an ideal, pre-configured volatile storage block5. If additional space is required, an administrator can override this by editing /etc/systemd/logind.conf or providing a drop-in snippet in /etc/systemd/logind.conf.d/ to increase the percentage5. -To utilize this mechanism, the browser's cache parent directory is remapped to the volatile runtime directory. - - -Configuration Step - Execution Location - Target Value / Command - Outcome - Identify User ID - Terminal Emulator - id -u - Retrieves the numerical user identifier (e.g., 1000) required for the path2. - Remap Cache Directory - about:config - browser.cache.disk.parent_directory = /run/user/1000/firefox - Instructs Firefox to build its cache2 directory inside the system's volatile RAM block2. - Verify Execution - Firefox URL Bar - about:cache - Confirms that the active cache location reflects the tmpfs mount path2. - When Firefox initializes, it will construct its cache2 directory within this RAM-disk12. Controlled benchmarks across modern architectures indicate that migrating cache read operations from an NVMe SSD to a RAM disk reduces median cache read latency from approximately 217 µs down to 14 µs, yielding 63–85% faster page resource loading under high-tab-load conditions1. -Complete Profile Virtualization: Profile-Sync-Daemon (PSD) -While caching web assets in RAM significantly improves page load times, Firefox's entire user profile—which encompasses SQLite databases containing history, bookmarks, DOM storage, and extension states—is continually subjected to disk I/O5. Relocating the entire profile to RAM guarantees that all browser operations occur at the speed of the DDR5 bus, vastly improving the responsiveness of the user interface, search bar queries, and tab switching5. -For Arch Linux running kernel 7.1, the definitive tool for this operation is profile-sync-daemon (psd). Available in the Arch official repositories, psd is a specialized pseudo-daemon that manages browser profiles in tmpfs and continuously synchronizes them with the physical disk using rsync5. -Architectural Mechanics of PSD and fuse-overlayfs -Legacy implementations of RAM-disks required copying the entire profile into memory at boot, and copying the entirety of it back upon shutdown. With large profiles, this induced unacceptable latency during login and logout sequences, and risked data loss during ungraceful shutdowns5. -Starting with version 7, psd leverages fuse-overlayfs (requiring a Linux kernel version of 4.18 or greater)5. OverlayFS is a union filesystem that fundamentally alters how the RAM disk operates. When psd initializes, it mounts a read-only base copy (the "lower directory") of the Firefox profile directly from the physical drive. It then creates a writable "upper directory" entirely within the /run/user/1000/psd tmpfs RAM allocation17. -All read operations seamlessly pass through to the underlying data, but crucially, all write operations (new history entries, updated cookies, extension state changes) are captured instantly in the volatile RAM layer18. During the synchronization interval, psd only needs to flush the highly localized changed data (the delta) back to the physical disk via rsync, rather than moving the entire profile5. This drastically reduces the memory footprint required in tmpfs and maximizes synchronization speed, making the user experience entirely transparent5. -Deployment and Systemd Configuration -To deploy psd optimally on a 64GB Arch system, the package is installed via pacman -S profile-sync-daemon16. Executing psd once in the terminal generates the initial configuration file at $XDG_CONFIG_HOME/psd/psd.conf16. -The configuration file must be modified to enforce overlayfs and target the specific browser. - - -psd.conf Directive - Target Value - Architectural Impact - USE_OVERLAYFS - "yes" - Mandates the use of the union filesystem, preventing full-profile copying and lowering sync latency5. - BROWSERS - "firefox" - Explicitly defines the target application, bypassing auto-detection overhead16. - USE_BACKUPS - "yes" - Enables automatic date-time-stamped crash recovery snapshots, protecting against unclean shutdowns5. - BACKUP_LIMIT - "5" - Retains the last five known-good profile states on the physical disk5. - Once configured, the daemon is activated via the systemd user service: systemctl --user enable --now psd.service5. -Systemd Timer Granularity Optimization -By default, the psd-resync.timer triggers a sync operation back to the physical disk every hour5. In a high-performance environment, leaving data purely volatile for an hour presents an unnecessary data-loss risk, especially when syncing deltas takes milliseconds due to fuse-overlayfs. The synchronization interval must be aggressively shortened. -This is achieved by extending the systemd user timer with a drop-in configuration file5. A directory is created at ~/.config/systemd/user/psd-resync.timer.d/, and a file named frequency.conf is populated with the following parameters: - - - - - - -Ini, TOML -[Unit] -Description=Timer for Profile-sync-daemon - 10min - -[Timer] -OnUnitActiveSec= -OnUnitActiveSec=10min - -Following a daemon reload (systemctl --user daemon-reload), the profile will exist natively in DDR5 RAM, writing changes back to the SSD every 10 minutes in the background without blocking the Firefox main execution thread5. -Unthrottling the Fission Architecture: Process Expansion -Modern Firefox utilizes a multi-process architecture known as Electrolysis (e10s), heavily augmented by Project Fission (Site Isolation)6. Fission is a fundamental security and performance paradigm that ensures that web pages and web frames from different origins are sandboxed into completely isolated OS-level processes7. -By default, to prevent users with limited RAM from encountering Out-Of-Memory (OOM) fatal errors, Firefox artificially caps the number of content processes it spawns. For shared web content, the default cap is 8 (dom.ipc.processCount). For isolated web content under Fission, the default cap per-site is 1, scaling up dynamically but with hard limits3. -When a user opens more tabs than the allocated process limits allow, Firefox is forced to bundle disparate pages into the same shared content processes21. This creates severe CPU thread contention, increases garbage collection (GC) latency, and renders the browser sluggish. Furthermore, sharing processes leads to "ghost window" memory leaks, where memory from a closed tab cannot be freed because the underlying OS process is being kept alive by an active tab sharing the same sandbox3. -With 64GB of DDR5 RAM, memory starvation is an impossibility under normal workloads. Therefore, the browser must be configured to prioritize maximum parallelism, dedicating a unique CPU thread and a unique block of memory to every single web asset. -Forcing Maximum Process Allocation -To unthrottle the multi-process limits, parameters in about:config must be adjusted to bypass standard memory-saving constraints. - - -Preference Name - Data Type - Target Value - Mechanism of Action - dom.ipc.processCount - Integer - 32 (or higher) - Defines the maximum number of shared web content processes. Increasing this ensures that legacy or non-isolated pages never have to share an execution thread9. - dom.ipc.processCount.webIsolated - Integer - 99 - Determines the number of processes allocated per site under Fission. Setting this to an arbitrarily high number guarantees strict 1:1 mapping of origins to OS processes, preventing ghost windows19. - dom.ipc.processCount.extension - Integer - 4 - Allows WebExtensions to run across multiple processes rather than a single shared sandbox, preventing heavy background scripts from locking the UI thread3. - fission.autostart - Boolean - true - Enforces Site Isolation architecture globally, ensuring that every origin is granted its own memory space6. - Increasing the webIsolated limit will cause the active process count in system monitors to scale linearly with the number of open tabs. Each process incurs roughly 30MB to 65MB of baseline overhead23. On a 64GB system, opening hundreds of tabs mapped strictly to distinct processes will efficiently utilize the hardware, transforming idle RAM into tangible responsiveness without triggering OS paging limits22. -Disabling Premature Memory Reclamation -Firefox features an internal daemon that monitors system memory and aggressively unloads background tabs if it perceives a low-memory state (browser.tabs.unloadOnLowMemory)9. While useful on restricted hardware, this daemon can miscalculate thresholds on massive RAM pools and artificially suspend background tabs, causing a delay when the user switches back to them14. -To prevent Firefox from unnecessarily dumping data out of RAM, this feature must be explicitly managed. The variable browser.tabs.unloadOnLowMemory can be set to false, entirely forbidding Firefox from suspending tabs based on memory pressure14. Alternatively, if an administrator wishes to retain it as an extreme fail-safe, the threshold must be remapped. By setting the integer browser.tabs.unloadOnLowMemory.thresholdMB to a high value (e.g., 2048), the browser will only discard tabs if less than 2GB of physical RAM remains completely free20. -Rendering Pipeline and Hardware Acceleration on Wayland -Migrating cache and profile operations into RAM resolves I/O latency, but visual stuttering and high CPU utilization are dictated by the graphics pipeline. Firefox 152 must be forced to utilize the GPU for all compositing and video decoding tasks, circumventing the CPU entirely. -Forcing WebRender -Firefox is powered by WebRender, a high-performance 2D rendering engine written in Rust2. On Linux, Mozilla occasionally employs a blocklist that forces a fallback to "Software WebRender" (which utilizes the CPU) if it detects certain graphics drivers, even on capable hardware2. -To confirm WebRender is active, users can navigate to about:support and locate the "Compositing" field. If it reads "Software WebRender" or "Basic," the hardware blocklist must be manually overridden in about:config2. -Setting gfx.webrender.all to true and layers.acceleration.force-enabled to true forces the browser to upload rendering tasks to the GPU24. This dramatically smooths out scrolling on high-refresh-rate monitors and frees up CPU cycles for script execution. -Hardware Video Acceleration (VA-API and DMA-BUF) -Without hardware acceleration, playing high-resolution video streams (e.g., AV1 or VP9 at 4K60FPS) forces the CPU to decode the frames algorithmically. This results in massive heat generation, CPU spikes up to 50%, and dropped frames4. Linux utilizes the Video Acceleration API (VA-API) to pass this workload directly to the GPU's dedicated hardware decoding silicon4. -To ensure Firefox taps directly into the hardware decoder under Wayland, specific directives must be enabled. - - -Preference Name - Data Type - Target Value - Mechanism of Action - media.ffmpeg.vaapi.enabled - Boolean - true - Enables the integration between Firefox's media framework and the system's VA-API libraries25. - media.hardware-video-decoding.force-enabled - Boolean - true - Overrides any internal blocklists that may prevent hardware video decoding on specific Linux drivers14. - widget.wayland-dmabuf-vaapi.enabled - Boolean - true - Enables zero-copy video decoding using Direct Memory Access Buffers under Wayland25. - The DMA-BUF implementation is critical for optimal performance. It allows the GPU to decode the video frame and pass the memory pointer directly to the Wayland compositor. This bypasses the need to copy the uncompressed frame through the CPU or system RAM, achieving a zero-copy pipeline that maximizes efficiency14. -Wayland Native Execution: Hyprland Environmental Configuration -Hyprland is a dynamic, wlroots-based Wayland compositor (currently transitioning to an independent backend)28. Firefox is capable of running natively under Wayland. However, if the system environment variables are misconfigured, Firefox will fall back to Xwayland—an X11 compatibility layer30. Xwayland introduces scaling artifacts (especially on HiDPI displays), lacks Wayland's security isolation, and breaks pixel-perfect trackpad kinetic scrolling29. -To strictly enforce native Wayland operation, the variable MOZ_ENABLE_WAYLAND=1 must be passed to the browser26. -Hyprland 0.55+ Configuration Architecture -As of June 2026, relying on legacy files such as /etc/environment to set Wayland variables is heavily discouraged, as it pollutes Xorg sessions and conflicts with modern session management paradigms32. -In Hyprland versions 0.55 and above, configuration has shifted to Lua syntax, and environments are increasingly managed by the Universal Wayland Session Manager (uwsm)32. Environment variables must be injected directly into the compositor's initialization phase. -If running standard Hyprland without uwsm, the variables are declared in the Lua configuration script: - - - - - - -Lua -hl.env("MOZ_ENABLE_WAYLAND", "1") -hl.env("XDG_CURRENT_DESKTOP", "Hyprland") -hl.env("XDG_SESSION_TYPE", "wayland") - -If the system leverages uwsm, environment variables must instead be exported via ~/.config/uwsm/env or ~/.config/uwsm/env-hyprland, using standard export syntax (e.g., export MOZ_ENABLE_WAYLAND=1)32. -Wayland-Specific Renderer Tuning -Wayland compositors handle window surfaces differently than X11. A common rendering glitch when maximizing hardware-accelerated video in Firefox under Hyprland is a brief flicker or blanking of the screen. This occurs as the compositor negotiates the opaque region of the window surface with the browser14. -This artifact can be entirely eliminated by instructing Firefox to ignore opaque region declarations to the compositor, by setting widget.wayland.opaque-region.enabled to false in about:config14. -Furthermore, to enable physics-based kinetic scrolling that matches system UI frameworks, and to ensure high-resolution input events from trackpads are captured seamlessly via XInput2 APIs, the variable apz.gtk.kinetic_scroll.enabled must be set to true, and MOZ_USE_XINPUT2=1 must be exported alongside the Wayland environment variables14. -Advanced Database Vacuuming, Telemetry Purging, and Network Optimization -Even with the profile residing completely in a tmpfs RAM disk, the internal structure of the SQLite databases (which store History, Bookmarks, and DOM data) becomes heavily fragmented over time14. When a user adds and removes bookmarks or generates thousands of history entries, the SQLite files develop empty, unused pages known as slack space. Firefox must parse over this dead space during queries, causing localized CPU spikes. -Vacuuming via Profile-Cleaner -To mathematically optimize the databases, an Arch package known as profile-cleaner can be utilized34. profile-cleaner iterates through the active Firefox profile and executes the VACUUM and REINDEX SQLite commands35. The VACUUM command rebuilds the database file from scratch, discarding all fragmented slack space, while REINDEX rebuilds the search indices, ensuring that queries (such as typing in the URL bar) are resolved instantly36. -Because the entire profile is actively hosted in tmpfs (RAM) via psd, executing profile-cleaner takes fractions of a second and incurs zero disk writes, optimizing the internal data structures purely in memory35. Automating this process via a systemd timer to execute weekly guarantees that database latency remains absolute zero. -Telemetry Elimination -Firefox includes extensive telemetry daemons that monitor performance and upload data to Mozilla. These background services consume CPU cycles, generate network interrupts, and produce unnecessary memory allocations9. On a system tuned for absolute maximum performance, these must be disabled. - - -Preference Name - Target Value - Architectural Impact - toolkit.telemetry.enabled - false - Completely disables the primary telemetry engine, freeing background threads9. - datareporting.healthreport.uploadEnabled - false - Halts the generation and upload of browser health metrics9. - app.normandy.enabled - false - Disables the Normandy remote-configuration engine, preventing background studies and unexpected configuration shifts9. - For extreme optimization, the crash-reporting binaries (crashreporter, minidump-analyzer, and pingsender) located in /usr/lib/firefox/ can be physically removed, and their paths added to the NoExtract parameter in /etc/pacman.conf to prevent reinstallation during package upgrades14. -Network Pipelining and Connection Ceilings -Finally, to guarantee that Firefox is actively utilizing the system's underlying network throughput to match the speed of the DDR5 RAM, the internal networking daemon must be permitted to open maximum parallel connections. -In about:config, the connection ceilings must be raised: -* network.http.max-connections = 1800 (Drastically increasing simultaneous TCP/UDP connection ceilings)9 -* network.http.max-persistent-connections-per-server = 10 -[cite: 9] -Additionally, enabling DNS over HTTPS (DoH) utilizing a fast provider (e.g., Cloudflare via network.trr.mode = 2 and network.trr.uri = https://mozilla.cloudflare-dns.com/dns-query) prevents legacy local DNS resolver latency from bottlenecking the initial connection handshake9. -Conclusion -The deployment of Mozilla Firefox 152 on an Arch Linux system running kernel 7.1 and the Hyprland Wayland compositor presents a unique opportunity for optimization. By actively disregarding legacy configuration logic meant to coddle resource-starved machines, the massive 64GB DDR5 hardware allocation can be fully exploited to create an essentially zero-latency browsing experience. -Through the strategic deployment of fuse-overlayfs via the profile-sync-daemon, the browser profile is completely decoupled from NVMe SSD latencies, achieving instantaneous read and write speeds within a tmpfs RAM disk. By overriding the internal cache calculators, redirecting cache directories to volatile memory, and forcing the Fission architecture to dedicate independent OS-level processes to every single origin, Firefox is transformed into a heavily parallelized application that safely absorbs available hardware resources. Coupled with native Wayland environment declarations, zero-copy DMA-BUF video decoding, enforced GPU WebRendering, and aggressive SQLite database vacuuming, this holistic configuration completely eliminates traditional browser bottlenecks, achieving the absolute apex of performance metrics. -Works cited - 1. Move Firefox and Chrome Cache to RAM Disk for Faster Browsing - LifeTips - Alibaba.com, https://lifetips.alibaba.com/tech-efficiency/move-firefox-and-chromes-cache-to-a-ram-disk-for-faster - 2. Firefox/Tweaks - ArchWiki, https://wiki.archlinux.org/title/Firefox/Tweaks - 3. Can somebody help me fix this? See comment. : r/firefox - Reddit, https://www.reddit.com/r/firefox/comments/1iqemqi/can_somebody_help_me_fix_this_see_comment/ - 4. Hardware video acceleration - ArchWiki, https://wiki.archlinux.org/title/Hardware_video_acceleration - 5. Profile-sync-daemon - ArchWiki, https://wiki.archlinux.org/title/Profile-sync-daemon - 6. How to Optimize Firefox for Performance: Evidence-Based Steps - LifeTips, https://lifetips.alibaba.com/tech-efficiency/optimize-firefox-for-performance - 7. Project Fission - MozillaWiki, https://wiki.mozilla.org/Project_Fission - 8. Speed Up Firefox by Moving Your Cache to RAM, No RAM Disk Required - Lifehacker, https://lifehacker.com/speed-up-firefox-by-moving-your-cache-to-ram-no-ram-di-5687850 - 9. Firefox Optimization Tweaks for 2025: Speed, Efficiency, and Privacy Perfected, https://eagleeyet.net/blog/web-browser/mozilla-firefox/firefox-optimization-tweaks-for-2025-speed-efficiency-and-privacy-perfected/ - 10. Disable browser cache in Firefox so you don't cause unnecessary writes to your SSD when watching Youtube videos/live streams - Reddit, https://www.reddit.com/r/firefox/comments/ufozuh/disable_browser_cache_in_firefox_so_you_dont/ - 11. Switched browser cache from disk (SSD) to RAM, about:cache still displaying in disk too | Firefox Support Forum, https://support.mozilla.org/en-US/questions/1313570 - 12. How to locate and change Firefox Cache storage location - Mozilla Support, https://support.mozilla.org/en-US/questions/1317032 - 13. Keep Your Browser Profiles In tmpfs (RAM) For Reduced Disk Writes And Increased Performance With Profile Sync Daemon - WebUpd8, http://www.webupd8.org/2013/02/keep-your-browser-profiles-in-tmpfs-ram.html - 14. Firefox - ArchWiki, https://wiki.archlinux.org/title/Firefox - 15. GitHub - graysky2/profile-sync-daemon: Symlinks and syncs browser profile dirs to RAM thus reducing HDD/SDD calls and speeding-up browsers., https://github.com/graysky2/profile-sync-daemon - 16. How To Sync Browser Profile Into Tmpfs (RAM) In Linux - OSTechNix, https://ostechnix.com/how-to-sync-browser-profile-into-tmpfs-ram-in-linux/ - 17. psd(1) — Arch manual pages, https://man.archlinux.org/man/psd.1 - 18. profile-sync-daemon(1) - Debian Manpages, https://manpages.debian.org/stretch/profile-sync-daemon/profile-sync-daemon.1.en.html - 19. Process Model — Firefox Source Docs documentation - Mozilla, https://firefox-source-docs.mozilla.org/dom/ipc/process_model.html - 20. Dealing with Firefox Memory Issues: Evidence-Based Fixes That Work - LifeTips, https://lifetips.alibaba.com/tech-efficiency/dealing-with-firefox-memory-issues - 21. Firefox content process limit is gone - Reddit, https://www.reddit.com/r/firefox/comments/r69j52/firefox_content_process_limit_is_gone/ - 22. 1742892 - Add UI for Fission-specific dom.ipc.processCount.webIsolated to replace "Content process limit" option in the preferences/settings - Bugzilla@Mozilla, https://bugzilla.mozilla.org/show_bug.cgi?id=1742892 - 23. 1470280 - Increase process count to 8 on Nightly - Bugzilla@Mozilla, https://bugzilla.mozilla.org/show_bug.cgi?id=1470280 - 24. Optimize_Firefox.md - GitHub, https://gist.github.com/kRHYME7/84ef0f69872eb9b92deb2a0aa4b869bf - 25. High CPU Usage in All Firefox-Based Browsers : r/hyprland - Reddit, https://www.reddit.com/r/hyprland/comments/1ntizop/high_cpu_usage_in_all_firefoxbased_browsers/ - 26. [How to] Wayland Firefox and Thunderbird under KDE or GNOME - Manjaro Linux Forum, https://forum.manjaro.org/t/how-to-wayland-firefox-and-thunderbird-under-kde-or-gnome/139120 - 27. Firefox 80 EGL and WebRender does not work - Linux - NVIDIA Developer Forums, https://forums.developer.nvidia.com/t/firefox-80-egl-and-webrender-does-not-work/140383 - 28. Hyprland, https://hypr.land/ - 29. Hyprland Setup Guide: Install and Configure (2026) - Petronella Technology Group, https://petronellatech.com/blog/hyprland-setup-guide-install-configure-2026/ - 30. Wayland - ArchWiki, https://wiki.archlinux.org/title/Wayland - 31. Most likely ruined my Arch installation by changing Environment variable to use Firefox on Wayland. Please help me save it. - Reddit, https://www.reddit.com/r/linux4noobs/comments/18nz135/most_likely_ruined_my_arch_installation_by/ - 32. Environment variables - Hyprland Wiki, https://wiki.hypr.land/Configuring/Advanced-and-Cool/Environment-variables/ - 33. Environment Variables - Hyprland Wiki, https://wiki.hypr.land/0.18.0beta/Configuring/Environment-variables/ - 34. profile-cleaner 2.46-1 (any) - Arch Linux, https://archlinux.org/packages/extra/any/profile-cleaner/ - 35. profile-cleaner reduces browser profile size by cleaning/reindexing - Arch Linux Forums, https://bbs.archlinux.org/viewtopic.php?id=148062 +Advanced Firefox 152 Performance Optimization on Arch Linux and Hyprland: Maximizing Volatile Memory Utilization +Introduction to Modern Browser Optimization on High-Performance Architectures +In the contemporary landscape of high-performance computing, the traditional bottlenecks of web browsing—network latency and graphical rendering throughput—have been largely superseded by local resource mismanagement. On a bleeding-edge system running Arch Linux (specifically Kernel 7.1.0), the Hyprland Wayland compositor, and Mozilla Firefox 152.0.2, paired with 64 Gigabytes of DDR5 RAM, the default configuration of any web browser represents a severe underutilization of available hardware. Standard browser architectures are conservatively engineered to operate within the constrained parameters of 8GB to 16GB memory footprints1. Consequently, they aggressively page out memory to disk, artificially limit concurrent processing, and rely on legacy disk-caching mechanisms that waste the immense bandwidth provided by DDR5 volatile memory2. +The optimization of Firefox 152 on such an architecture requires a fundamental paradigm shift: moving from a disk-bound input/output (I/O) model to a fully memory-bound execution environment. By leveraging Linux kernel features such as tmpfs, fuse-overlayfs, and direct hardware integration via the Video Acceleration API (VA-API) and Direct Media Access Buffer (DMA-BUF), it is possible to entirely eliminate solid-state drive (SSD) latency from the browser's critical path4. Furthermore, the immense 64GB RAM capacity allows for the unthrottling of Firefox’s Electrolysis (e10s) and Fission (Site Isolation) architectures, dedicating discrete operating system-level processes to every individual web origin6. +This comprehensive report provides an exhaustive, critical analysis of the absolute latest methodologies to force Firefox 152 to consume as much volatile memory as necessary to achieve instantaneous responsiveness. The analysis is tailored exclusively for a pure Wayland environment on Arch Linux, ensuring that no legacy X11 or deprecated methodologies are utilized. +Re-architecting Cache Topologies: Eliminating Disk I/O +Every object loaded by Firefox—HTML payloads, JavaScript bundles, WebAssembly modules, and media assets—is cached to prevent redundant network requests. By default, Firefox maintains a dual-cache hierarchy: a high-speed memory cache and a persistent disk cache2. On a system equipped with 64GB of DDR5 RAM, writing temporary web assets to an NVMe SSD is an architectural inefficiency that introduces micro-stutters during concurrent heavy workloads (e.g., rendering dozens of Document Object Models simultaneously)1. +To force Firefox to utilize RAM for all caching operations, two distinct methodologies can be deployed. The first relies on Firefox's native internal memory allocator, while the second leverages the Linux kernel's tmpfs virtual filesystem. +Native Memory Cache Override +The most direct approach to stopping disk I/O is to disable Firefox's disk cache entirely and force all caching into the application's allocated memory space. Through the about:config interface, the native disk cache must be disabled, and the memory cache must be confirmed as active2. +However, a critical scaling issue exists within Firefox's internal logic. By default, the memory cache capacity is determined dynamically. The internal formula used by Firefox to calculate this dynamic limit is: + + +This calculation is based on an archaic table designed for systems with 8GB of system memory or less2. On a 64GB system, this formula asymptotes prematurely, allocating a trivially small amount of RAM (often less than 50MB) to the cache. Therefore, relying on the automatic size selection will starve the browser of cache space. +To resolve this, the capacity must be manually defined. For a 64GB system, allocating 4GB of RAM specifically for internal web caching is optimal. + + +Preference Name + Data Type + Target Value + Mechanism of Action + browser.cache.disk.enable + Boolean + false + Disables disk-based caching, halting SSD write wear for web assets and preventing I/O latency2. + browser.cache.memory.enable + Boolean + true + Forces the browser to retain cached objects entirely in volatile memory2. + browser.cache.memory.capacity + Integer + 4194304 + Allocates exactly 4,194,304 KB (4 GB) of RAM to the internal cache, bypassing the deprecated legacy dynamic scaling algorithm2. + browser.cache.disk.smart_size.enabled + Boolean + false + Prevents the browser from attempting to dynamically resize the disabled disk cache10. + browser.cache.disk_cache_ssl + Boolean + false + Ensures encrypted HTTPS payloads are not forced to the disk cache independently of the primary cache directive10. + browser.cache.offline.enable + Boolean + false + Disables offline caching mechanics which default to disk writing10. + The primary drawback of the native memory cache is that it is entirely ephemeral. In the event of a browser crash or a system reboot, the cache is destroyed, necessitating the re-download of all assets upon subsequent visits2. +Kernel-Level Volatile Caching (tmpfs) +An alternative to the native memory override—and one that offers superior integration with the Linux kernel's page cache and survives browser restarts—is to leave the disk cache enabled within Firefox, but forcefully redirect the read/write operations to a RAM-backed filesystem (tmpfs). +In modern Arch Linux environments managed by systemd, a user-specific tmpfs is automatically mounted at /run/user/ (typically /run/user/1000)5. This directory exists entirely in RAM. The size of this tmpfs is governed by the RuntimeDirectorySize directive in /etc/systemd/logind.conf5. By default, systemd caps this directory at 10% of physical memory (6.4GB on a 64GB system), which provides an ideal, pre-configured volatile storage block5. If additional space is required, an administrator can override this by editing /etc/systemd/logind.conf or providing a drop-in snippet in /etc/systemd/logind.conf.d/ to increase the percentage5. +To utilize this mechanism, the browser's cache parent directory is remapped to the volatile runtime directory. + + +Configuration Step + Execution Location + Target Value / Command + Outcome + Identify User ID + Terminal Emulator + id -u + Retrieves the numerical user identifier (e.g., 1000) required for the path2. + Remap Cache Directory + about:config + browser.cache.disk.parent_directory = /run/user/1000/firefox + Instructs Firefox to build its cache2 directory inside the system's volatile RAM block2. + Verify Execution + Firefox URL Bar + about:cache + Confirms that the active cache location reflects the tmpfs mount path2. + When Firefox initializes, it will construct its cache2 directory within this RAM-disk12. Controlled benchmarks across modern architectures indicate that migrating cache read operations from an NVMe SSD to a RAM disk reduces median cache read latency from approximately 217 µs down to 14 µs, yielding 63–85% faster page resource loading under high-tab-load conditions1. +Complete Profile Virtualization: Profile-Sync-Daemon (PSD) +While caching web assets in RAM significantly improves page load times, Firefox's entire user profile—which encompasses SQLite databases containing history, bookmarks, DOM storage, and extension states—is continually subjected to disk I/O5. Relocating the entire profile to RAM guarantees that all browser operations occur at the speed of the DDR5 bus, vastly improving the responsiveness of the user interface, search bar queries, and tab switching5. +For Arch Linux running kernel 7.1, the definitive tool for this operation is profile-sync-daemon (psd). Available in the Arch official repositories, psd is a specialized pseudo-daemon that manages browser profiles in tmpfs and continuously synchronizes them with the physical disk using rsync5. +Architectural Mechanics of PSD and fuse-overlayfs +Legacy implementations of RAM-disks required copying the entire profile into memory at boot, and copying the entirety of it back upon shutdown. With large profiles, this induced unacceptable latency during login and logout sequences, and risked data loss during ungraceful shutdowns5. +Starting with version 7, psd leverages fuse-overlayfs (requiring a Linux kernel version of 4.18 or greater)5. OverlayFS is a union filesystem that fundamentally alters how the RAM disk operates. When psd initializes, it mounts a read-only base copy (the "lower directory") of the Firefox profile directly from the physical drive. It then creates a writable "upper directory" entirely within the /run/user/1000/psd tmpfs RAM allocation17. +All read operations seamlessly pass through to the underlying data, but crucially, all write operations (new history entries, updated cookies, extension state changes) are captured instantly in the volatile RAM layer18. During the synchronization interval, psd only needs to flush the highly localized changed data (the delta) back to the physical disk via rsync, rather than moving the entire profile5. This drastically reduces the memory footprint required in tmpfs and maximizes synchronization speed, making the user experience entirely transparent5. +Deployment and Systemd Configuration +To deploy psd optimally on a 64GB Arch system, the package is installed via pacman -S profile-sync-daemon16. Executing psd once in the terminal generates the initial configuration file at $XDG_CONFIG_HOME/psd/psd.conf16. +The configuration file must be modified to enforce overlayfs and target the specific browser. + + +psd.conf Directive + Target Value + Architectural Impact + USE_OVERLAYFS + "yes" + Mandates the use of the union filesystem, preventing full-profile copying and lowering sync latency5. + BROWSERS + "firefox" + Explicitly defines the target application, bypassing auto-detection overhead16. + USE_BACKUPS + "yes" + Enables automatic date-time-stamped crash recovery snapshots, protecting against unclean shutdowns5. + BACKUP_LIMIT + "5" + Retains the last five known-good profile states on the physical disk5. + Once configured, the daemon is activated via the systemd user service: systemctl --user enable --now psd.service5. +Systemd Timer Granularity Optimization +By default, the psd-resync.timer triggers a sync operation back to the physical disk every hour5. In a high-performance environment, leaving data purely volatile for an hour presents an unnecessary data-loss risk, especially when syncing deltas takes milliseconds due to fuse-overlayfs. The synchronization interval must be aggressively shortened. +This is achieved by extending the systemd user timer with a drop-in configuration file5. A directory is created at ~/.config/systemd/user/psd-resync.timer.d/, and a file named frequency.conf is populated with the following parameters: + + + + + + +Ini, TOML +[Unit] +Description=Timer for Profile-sync-daemon - 10min + +[Timer] +OnUnitActiveSec= +OnUnitActiveSec=10min + +Following a daemon reload (systemctl --user daemon-reload), the profile will exist natively in DDR5 RAM, writing changes back to the SSD every 10 minutes in the background without blocking the Firefox main execution thread5. +Unthrottling the Fission Architecture: Process Expansion +Modern Firefox utilizes a multi-process architecture known as Electrolysis (e10s), heavily augmented by Project Fission (Site Isolation)6. Fission is a fundamental security and performance paradigm that ensures that web pages and web frames from different origins are sandboxed into completely isolated OS-level processes7. +By default, to prevent users with limited RAM from encountering Out-Of-Memory (OOM) fatal errors, Firefox artificially caps the number of content processes it spawns. For shared web content, the default cap is 8 (dom.ipc.processCount). For isolated web content under Fission, the default cap per-site is 1, scaling up dynamically but with hard limits3. +When a user opens more tabs than the allocated process limits allow, Firefox is forced to bundle disparate pages into the same shared content processes21. This creates severe CPU thread contention, increases garbage collection (GC) latency, and renders the browser sluggish. Furthermore, sharing processes leads to "ghost window" memory leaks, where memory from a closed tab cannot be freed because the underlying OS process is being kept alive by an active tab sharing the same sandbox3. +With 64GB of DDR5 RAM, memory starvation is an impossibility under normal workloads. Therefore, the browser must be configured to prioritize maximum parallelism, dedicating a unique CPU thread and a unique block of memory to every single web asset. +Forcing Maximum Process Allocation +To unthrottle the multi-process limits, parameters in about:config must be adjusted to bypass standard memory-saving constraints. + + +Preference Name + Data Type + Target Value + Mechanism of Action + dom.ipc.processCount + Integer + 32 (or higher) + Defines the maximum number of shared web content processes. Increasing this ensures that legacy or non-isolated pages never have to share an execution thread9. + dom.ipc.processCount.webIsolated + Integer + 99 + Determines the number of processes allocated per site under Fission. Setting this to an arbitrarily high number guarantees strict 1:1 mapping of origins to OS processes, preventing ghost windows19. + dom.ipc.processCount.extension + Integer + 4 + Allows WebExtensions to run across multiple processes rather than a single shared sandbox, preventing heavy background scripts from locking the UI thread3. + fission.autostart + Boolean + true + Enforces Site Isolation architecture globally, ensuring that every origin is granted its own memory space6. + Increasing the webIsolated limit will cause the active process count in system monitors to scale linearly with the number of open tabs. Each process incurs roughly 30MB to 65MB of baseline overhead23. On a 64GB system, opening hundreds of tabs mapped strictly to distinct processes will efficiently utilize the hardware, transforming idle RAM into tangible responsiveness without triggering OS paging limits22. +Disabling Premature Memory Reclamation +Firefox features an internal daemon that monitors system memory and aggressively unloads background tabs if it perceives a low-memory state (browser.tabs.unloadOnLowMemory)9. While useful on restricted hardware, this daemon can miscalculate thresholds on massive RAM pools and artificially suspend background tabs, causing a delay when the user switches back to them14. +To prevent Firefox from unnecessarily dumping data out of RAM, this feature must be explicitly managed. The variable browser.tabs.unloadOnLowMemory can be set to false, entirely forbidding Firefox from suspending tabs based on memory pressure14. Alternatively, if an administrator wishes to retain it as an extreme fail-safe, the threshold must be remapped. By setting the integer browser.tabs.unloadOnLowMemory.thresholdMB to a high value (e.g., 2048), the browser will only discard tabs if less than 2GB of physical RAM remains completely free20. +Rendering Pipeline and Hardware Acceleration on Wayland +Migrating cache and profile operations into RAM resolves I/O latency, but visual stuttering and high CPU utilization are dictated by the graphics pipeline. Firefox 152 must be forced to utilize the GPU for all compositing and video decoding tasks, circumventing the CPU entirely. +Forcing WebRender +Firefox is powered by WebRender, a high-performance 2D rendering engine written in Rust2. On Linux, Mozilla occasionally employs a blocklist that forces a fallback to "Software WebRender" (which utilizes the CPU) if it detects certain graphics drivers, even on capable hardware2. +To confirm WebRender is active, users can navigate to about:support and locate the "Compositing" field. If it reads "Software WebRender" or "Basic," the hardware blocklist must be manually overridden in about:config2. +Setting gfx.webrender.all to true and layers.acceleration.force-enabled to true forces the browser to upload rendering tasks to the GPU24. This dramatically smooths out scrolling on high-refresh-rate monitors and frees up CPU cycles for script execution. +Hardware Video Acceleration (VA-API and DMA-BUF) +Without hardware acceleration, playing high-resolution video streams (e.g., AV1 or VP9 at 4K60FPS) forces the CPU to decode the frames algorithmically. This results in massive heat generation, CPU spikes up to 50%, and dropped frames4. Linux utilizes the Video Acceleration API (VA-API) to pass this workload directly to the GPU's dedicated hardware decoding silicon4. +To ensure Firefox taps directly into the hardware decoder under Wayland, specific directives must be enabled. + + +Preference Name + Data Type + Target Value + Mechanism of Action + media.ffmpeg.vaapi.enabled + Boolean + true + Enables the integration between Firefox's media framework and the system's VA-API libraries25. + media.hardware-video-decoding.force-enabled + Boolean + true + Overrides any internal blocklists that may prevent hardware video decoding on specific Linux drivers14. + widget.wayland-dmabuf-vaapi.enabled + Boolean + true + Enables zero-copy video decoding using Direct Memory Access Buffers under Wayland25. + The DMA-BUF implementation is critical for optimal performance. It allows the GPU to decode the video frame and pass the memory pointer directly to the Wayland compositor. This bypasses the need to copy the uncompressed frame through the CPU or system RAM, achieving a zero-copy pipeline that maximizes efficiency14. +Wayland Native Execution: Hyprland Environmental Configuration +Hyprland is a dynamic, wlroots-based Wayland compositor (currently transitioning to an independent backend)28. Firefox is capable of running natively under Wayland. However, if the system environment variables are misconfigured, Firefox will fall back to Xwayland—an X11 compatibility layer30. Xwayland introduces scaling artifacts (especially on HiDPI displays), lacks Wayland's security isolation, and breaks pixel-perfect trackpad kinetic scrolling29. +To strictly enforce native Wayland operation, the variable MOZ_ENABLE_WAYLAND=1 must be passed to the browser26. +Hyprland 0.55+ Configuration Architecture +As of June 2026, relying on legacy files such as /etc/environment to set Wayland variables is heavily discouraged, as it pollutes Xorg sessions and conflicts with modern session management paradigms32. +In Hyprland versions 0.55 and above, configuration has shifted to Lua syntax, and environments are increasingly managed by the Universal Wayland Session Manager (uwsm)32. Environment variables must be injected directly into the compositor's initialization phase. +If running standard Hyprland without uwsm, the variables are declared in the Lua configuration script: + + + + + + +Lua +hl.env("MOZ_ENABLE_WAYLAND", "1") +hl.env("XDG_CURRENT_DESKTOP", "Hyprland") +hl.env("XDG_SESSION_TYPE", "wayland") + +If the system leverages uwsm, environment variables must instead be exported via ~/.config/uwsm/env or ~/.config/uwsm/env-hyprland, using standard export syntax (e.g., export MOZ_ENABLE_WAYLAND=1)32. +Wayland-Specific Renderer Tuning +Wayland compositors handle window surfaces differently than X11. A common rendering glitch when maximizing hardware-accelerated video in Firefox under Hyprland is a brief flicker or blanking of the screen. This occurs as the compositor negotiates the opaque region of the window surface with the browser14. +This artifact can be entirely eliminated by instructing Firefox to ignore opaque region declarations to the compositor, by setting widget.wayland.opaque-region.enabled to false in about:config14. +Furthermore, to enable physics-based kinetic scrolling that matches system UI frameworks, and to ensure high-resolution input events from trackpads are captured seamlessly via XInput2 APIs, the variable apz.gtk.kinetic_scroll.enabled must be set to true, and MOZ_USE_XINPUT2=1 must be exported alongside the Wayland environment variables14. +Advanced Database Vacuuming, Telemetry Purging, and Network Optimization +Even with the profile residing completely in a tmpfs RAM disk, the internal structure of the SQLite databases (which store History, Bookmarks, and DOM data) becomes heavily fragmented over time14. When a user adds and removes bookmarks or generates thousands of history entries, the SQLite files develop empty, unused pages known as slack space. Firefox must parse over this dead space during queries, causing localized CPU spikes. +Vacuuming via Profile-Cleaner +To mathematically optimize the databases, an Arch package known as profile-cleaner can be utilized34. profile-cleaner iterates through the active Firefox profile and executes the VACUUM and REINDEX SQLite commands35. The VACUUM command rebuilds the database file from scratch, discarding all fragmented slack space, while REINDEX rebuilds the search indices, ensuring that queries (such as typing in the URL bar) are resolved instantly36. +Because the entire profile is actively hosted in tmpfs (RAM) via psd, executing profile-cleaner takes fractions of a second and incurs zero disk writes, optimizing the internal data structures purely in memory35. Automating this process via a systemd timer to execute weekly guarantees that database latency remains absolute zero. +Telemetry Elimination +Firefox includes extensive telemetry daemons that monitor performance and upload data to Mozilla. These background services consume CPU cycles, generate network interrupts, and produce unnecessary memory allocations9. On a system tuned for absolute maximum performance, these must be disabled. + + +Preference Name + Target Value + Architectural Impact + toolkit.telemetry.enabled + false + Completely disables the primary telemetry engine, freeing background threads9. + datareporting.healthreport.uploadEnabled + false + Halts the generation and upload of browser health metrics9. + app.normandy.enabled + false + Disables the Normandy remote-configuration engine, preventing background studies and unexpected configuration shifts9. + For extreme optimization, the crash-reporting binaries (crashreporter, minidump-analyzer, and pingsender) located in /usr/lib/firefox/ can be physically removed, and their paths added to the NoExtract parameter in /etc/pacman.conf to prevent reinstallation during package upgrades14. +Network Pipelining and Connection Ceilings +Finally, to guarantee that Firefox is actively utilizing the system's underlying network throughput to match the speed of the DDR5 RAM, the internal networking daemon must be permitted to open maximum parallel connections. +In about:config, the connection ceilings must be raised: +* network.http.max-connections = 1800 (Drastically increasing simultaneous TCP/UDP connection ceilings)9 +* network.http.max-persistent-connections-per-server = 10 +[cite: 9] +Additionally, enabling DNS over HTTPS (DoH) utilizing a fast provider (e.g., Cloudflare via network.trr.mode = 2 and network.trr.uri = https://mozilla.cloudflare-dns.com/dns-query) prevents legacy local DNS resolver latency from bottlenecking the initial connection handshake9. +Conclusion +The deployment of Mozilla Firefox 152 on an Arch Linux system running kernel 7.1 and the Hyprland Wayland compositor presents a unique opportunity for optimization. By actively disregarding legacy configuration logic meant to coddle resource-starved machines, the massive 64GB DDR5 hardware allocation can be fully exploited to create an essentially zero-latency browsing experience. +Through the strategic deployment of fuse-overlayfs via the profile-sync-daemon, the browser profile is completely decoupled from NVMe SSD latencies, achieving instantaneous read and write speeds within a tmpfs RAM disk. By overriding the internal cache calculators, redirecting cache directories to volatile memory, and forcing the Fission architecture to dedicate independent OS-level processes to every single origin, Firefox is transformed into a heavily parallelized application that safely absorbs available hardware resources. Coupled with native Wayland environment declarations, zero-copy DMA-BUF video decoding, enforced GPU WebRendering, and aggressive SQLite database vacuuming, this holistic configuration completely eliminates traditional browser bottlenecks, achieving the absolute apex of performance metrics. +Works cited + 1. Move Firefox and Chrome Cache to RAM Disk for Faster Browsing - LifeTips - Alibaba.com, https://lifetips.alibaba.com/tech-efficiency/move-firefox-and-chromes-cache-to-a-ram-disk-for-faster + 2. Firefox/Tweaks - ArchWiki, https://wiki.archlinux.org/title/Firefox/Tweaks + 3. Can somebody help me fix this? See comment. : r/firefox - Reddit, https://www.reddit.com/r/firefox/comments/1iqemqi/can_somebody_help_me_fix_this_see_comment/ + 4. Hardware video acceleration - ArchWiki, https://wiki.archlinux.org/title/Hardware_video_acceleration + 5. Profile-sync-daemon - ArchWiki, https://wiki.archlinux.org/title/Profile-sync-daemon + 6. How to Optimize Firefox for Performance: Evidence-Based Steps - LifeTips, https://lifetips.alibaba.com/tech-efficiency/optimize-firefox-for-performance + 7. Project Fission - MozillaWiki, https://wiki.mozilla.org/Project_Fission + 8. Speed Up Firefox by Moving Your Cache to RAM, No RAM Disk Required - Lifehacker, https://lifehacker.com/speed-up-firefox-by-moving-your-cache-to-ram-no-ram-di-5687850 + 9. Firefox Optimization Tweaks for 2025: Speed, Efficiency, and Privacy Perfected, https://eagleeyet.net/blog/web-browser/mozilla-firefox/firefox-optimization-tweaks-for-2025-speed-efficiency-and-privacy-perfected/ + 10. Disable browser cache in Firefox so you don't cause unnecessary writes to your SSD when watching Youtube videos/live streams - Reddit, https://www.reddit.com/r/firefox/comments/ufozuh/disable_browser_cache_in_firefox_so_you_dont/ + 11. Switched browser cache from disk (SSD) to RAM, about:cache still displaying in disk too | Firefox Support Forum, https://support.mozilla.org/en-US/questions/1313570 + 12. How to locate and change Firefox Cache storage location - Mozilla Support, https://support.mozilla.org/en-US/questions/1317032 + 13. Keep Your Browser Profiles In tmpfs (RAM) For Reduced Disk Writes And Increased Performance With Profile Sync Daemon - WebUpd8, http://www.webupd8.org/2013/02/keep-your-browser-profiles-in-tmpfs-ram.html + 14. Firefox - ArchWiki, https://wiki.archlinux.org/title/Firefox + 15. GitHub - graysky2/profile-sync-daemon: Symlinks and syncs browser profile dirs to RAM thus reducing HDD/SDD calls and speeding-up browsers., https://github.com/graysky2/profile-sync-daemon + 16. How To Sync Browser Profile Into Tmpfs (RAM) In Linux - OSTechNix, https://ostechnix.com/how-to-sync-browser-profile-into-tmpfs-ram-in-linux/ + 17. psd(1) — Arch manual pages, https://man.archlinux.org/man/psd.1 + 18. profile-sync-daemon(1) - Debian Manpages, https://manpages.debian.org/stretch/profile-sync-daemon/profile-sync-daemon.1.en.html + 19. Process Model — Firefox Source Docs documentation - Mozilla, https://firefox-source-docs.mozilla.org/dom/ipc/process_model.html + 20. Dealing with Firefox Memory Issues: Evidence-Based Fixes That Work - LifeTips, https://lifetips.alibaba.com/tech-efficiency/dealing-with-firefox-memory-issues + 21. Firefox content process limit is gone - Reddit, https://www.reddit.com/r/firefox/comments/r69j52/firefox_content_process_limit_is_gone/ + 22. 1742892 - Add UI for Fission-specific dom.ipc.processCount.webIsolated to replace "Content process limit" option in the preferences/settings - Bugzilla@Mozilla, https://bugzilla.mozilla.org/show_bug.cgi?id=1742892 + 23. 1470280 - Increase process count to 8 on Nightly - Bugzilla@Mozilla, https://bugzilla.mozilla.org/show_bug.cgi?id=1470280 + 24. Optimize_Firefox.md - GitHub, https://gist.github.com/kRHYME7/84ef0f69872eb9b92deb2a0aa4b869bf + 25. High CPU Usage in All Firefox-Based Browsers : r/hyprland - Reddit, https://www.reddit.com/r/hyprland/comments/1ntizop/high_cpu_usage_in_all_firefoxbased_browsers/ + 26. [How to] Wayland Firefox and Thunderbird under KDE or GNOME - Manjaro Linux Forum, https://forum.manjaro.org/t/how-to-wayland-firefox-and-thunderbird-under-kde-or-gnome/139120 + 27. Firefox 80 EGL and WebRender does not work - Linux - NVIDIA Developer Forums, https://forums.developer.nvidia.com/t/firefox-80-egl-and-webrender-does-not-work/140383 + 28. Hyprland, https://hypr.land/ + 29. Hyprland Setup Guide: Install and Configure (2026) - Petronella Technology Group, https://petronellatech.com/blog/hyprland-setup-guide-install-configure-2026/ + 30. Wayland - ArchWiki, https://wiki.archlinux.org/title/Wayland + 31. Most likely ruined my Arch installation by changing Environment variable to use Firefox on Wayland. Please help me save it. - Reddit, https://www.reddit.com/r/linux4noobs/comments/18nz135/most_likely_ruined_my_arch_installation_by/ + 32. Environment variables - Hyprland Wiki, https://wiki.hypr.land/Configuring/Advanced-and-Cool/Environment-variables/ + 33. Environment Variables - Hyprland Wiki, https://wiki.hypr.land/0.18.0beta/Configuring/Environment-variables/ + 34. profile-cleaner 2.46-1 (any) - Arch Linux, https://archlinux.org/packages/extra/any/profile-cleaner/ + 35. profile-cleaner reduces browser profile size by cleaning/reindexing - Arch Linux Forums, https://bbs.archlinux.org/viewtopic.php?id=148062 36. graysky2/profile-cleaner: Simple script to vacuum and reindex sqlite databases used by Firefox and by Chrome/Chromium. - GitHub, https://github.com/graysky2/profile-cleaner \ No newline at end of file From 32964e64282579dc3151e01cd0500f17719fc105 Mon Sep 17 00:00:00 2001 From: Ainsley Woo <125954904+Kantosaurus@users.noreply.github.com> Date: Tue, 28 Jul 2026 17:20:03 +0800 Subject: [PATCH 4/5] docs: restructure README and add a changelog Rewrite the README with a structured landing (badges, table of contents, clearer install steps, grouped feature overview, contributing section) while preserving all existing content, and correct a few stale script paths and the cheatsheet keybind. Add CHANGELOG.md. --- CHANGELOG.md | 100 +++++++++++ README.md | 480 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 430 insertions(+), 150 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..c5878193a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,100 @@ +# Changelog + +All notable changes to Dusky are documented here. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +Dusky tracks Arch Linux, so it is a rolling configuration rather than a project with +long-lived release branches — `main` is always the supported version. + +Your installed version: + +```bash +cat ~/.config/dusky/version +``` + +> **Note on history:** Dusky was developed for its first several months without a +> changelog. Entries below `4.0` are therefore not reconstructed — the commit history +> from 2025-11-14 onward is the authoritative record for that period. Everything from +> `4.0` forward is tracked here. + +--- + +## [Unreleased] + +### Added + +- Open source project infrastructure: contributing guide, code of conduct, security + policy, support guide, issue and pull request templates. +- `lint` CI workflow — checks shell syntax, Python syntax, and CRLF line endings on every + push and pull request. +- `.gitattributes` pinning all text files to LF. Prevents a contributor with + `core.autocrlf=true` from committing scripts that fail on Arch with + `/usr/bin/env: 'bash\r': No such file or directory`. +- `.editorconfig` matching the existing 4-space convention. + +### Fixed + +- `user_scripts/dusky_tui/bash/for_equal_assignment_delimiter_only/dusky_tui_4.3.0.sh`: + an `if … then` block was closed with `}` instead of `fi`, which made the entire script + fail to parse and therefore impossible to run. +- README: corrected the setup subscript path + (`user_scripts/setup_scripts/scripts/` → `user_scripts/arch_setup_scripts/scripts/`) + and the drive manager path + (`user_scripts/drives/drive_manager.sh` → `user_scripts/drives/drive_manager/drive_manager.py`, + configured via `drives.toml`). +- README: removed a reference to `user_scripts/network_manager/nmcli_wifi.sh`, which does + not exist in the repository. + +--- + +## [4.0] + +The current release line. Highlights from this cycle: + +### Added + +- **Dusky Control Center** — a single GUI surface for system settings and features. +- **Firefox theming via Matugen**, built on + [MatugenFox](https://github.com/Ubaidullah-Web-Dev/MatugenFox), extending the unified + colour scheme into the browser. +- **`ai_bridge` Firefox extension** — bridges the desktop to browser-based AI chat sites, + with focus handling, workspace switching, and per-site configuration. +- **Matugen theming TUI** for managing themes and templates from the terminal. +- **Dusky ISO** — a fully offline Arch installer image built from + `user_scripts/arch_iso_scripts/`. +- **Gaming support** — FPS limiter and a gaming package setup script. +- **iOS sideloading tooling** under `user_scripts` and the accompanying notes in the + Obsidian vault. +- **Waybar layout options** — horizontal and vertical, selectable during setup and + toggleable from Rofi (block, circular, and minimal variants). +- **Network throttle** — traffic shaping and per-application quotas with a TUI, including + a pytest suite. + +### Changed + +- Reorganised `user_scripts/` into clearer functional directories. +- Template handling now supports multiple passes without duplicating entries, and + templates can be deleted or reset. + +--- + +## Release process + +Dusky does not currently tag releases. Adopting tags would let users pin a known-good +state and would give this changelog anchors to link to: + +```bash +# Bump the version file, then tag it. +echo "v4.1" > .config/dusky/version +git commit -am "release: v4.1" +git tag -a v4.1 -m "v4.1" +git push origin main --tags +``` + +GitHub will then generate a Releases page, and each entry here can link to its tag. + + diff --git a/README.md b/README.md index a554dbf43..e7aee4dc9 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,93 @@ -## If you need help with installation, troubleshooting or just want to hangout, join the Discord server. +
+ +# Dusky + +**A complete, batteries-included Arch Linux + Hyprland desktop.** + +The raw power and minimalism of Arch, with the install experience of a standard distro. +~900 MB idle RAM. Unified Matugen theming across the entire system, browser included. + +[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) +[![Arch Linux](https://img.shields.io/badge/Arch_Linux-1793D1?logo=arch-linux&logoColor=white)](https://archlinux.org/) +[![Hyprland](https://img.shields.io/badge/Hyprland-58E1FF?logo=hyprland&logoColor=black)](https://hyprland.org/) +[![lint](https://github.com/dusklinux/dusky/actions/workflows/lint.yml/badge.svg)](https://github.com/dusklinux/dusky/actions/workflows/lint.yml) +[![Stars](https://img.shields.io/github/stars/dusklinux/dusky?style=flat&color=yellow)](https://github.com/dusklinux/dusky/stargazers) +[![Discord](https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/Nv2a7yTBQS) +[**Install**](#-installation) · +[**Features**](#overview) · +[**Video tutorial**](https://youtu.be/OzeFAY_8T8Y) · +[**Discord**](https://discord.gg/Nv2a7yTBQS) · +[**Wallpapers**](https://github.com/dusklinux/images) · +[**Contributing**](.github/CONTRIBUTING.md) + +![Dusky Control Center](Pictures/readme_assets/dusky_control_center.webp) + +
-[Join Discord Server][discord] +--- + +This repository is the result of 8 months of tinkering, breaking, fixing and polishing. +It's a labor of love designed to feel as easy to install as a "standard" distribution, but +with the raw power and minimalism of Arch. **Please consider starring ⭐ this repo** as a +token of support. + +## Table of contents + +- [Getting help](#-getting-help) +- [Waybar layouts](#waybar-layouts) +- [Theming & acknowledgments](#-theming--acknowledgments) +- [Prerequisites & hardware](#️-prerequisites--hardware) +- [Installation](#-installation) +- [The Orchestra script](#the-orchestra-script) +- [Usage & keybinds](#️-usage--keybinds) +- [Troubleshooting](#-troubleshooting) +- [Overview — the full feature list](#overview) +- [Performance and system](#performance-and-system) +- [Graphics and gaming](#graphics-and-gaming) +- [Usability and theming](#usability-and-theming) +- [Contributing](#-contributing) +- [Acknowledgments](#acknowledgments) +- [License](#license) + +--- + +## 💬 Getting help + +If you need help with installation, troubleshooting or just want to hang out, join the +Discord server — it's where most support happens, and hardware-specific problems usually +get solved there in minutes. + +[**Join the Discord Server**][discord] [discord]: https://discord.gg/Nv2a7yTBQS -## Updated demo video now out on YouTube with all major features covered! -(since the release of this video around 5 major features have been added, scroll down to the `overview` section for details) +### 📺 Updated demo video now out on YouTube with all major features covered + +Since the release of this video, around 5 major features have been added — scroll down to +the [overview](#overview) section for details. -[Watch now][video] +[**Watch now**][video] [video]: https://youtu.be/JmgvSdEIK8c -### If you're here just for the wallpapers, you can get all of them (+1050 wallpapers) from my [images repo][images]. +### 🖼️ If you're here just for the wallpapers + +You can get all of them (1050+ wallpapers) from my [images repo][images]. [images]: https://github.com/dusklinux/images -### to get this out of the way cuz i'm getting so many questions about waybar. -YES YOU CAN HAVE HORIZONTAL WAYBAR. and you will be asked which side you want it on bottom/top/left/right. +--- + +## Waybar layouts + +To get this out of the way, because I'm getting so many questions about Waybar: + +**YES, YOU CAN HAVE A HORIZONTAL WAYBAR.** You'll be asked which side you want it on — +bottom, top, left or right. Horizontal and vertical are both available: take your pick +during setup, and it's easily toggleable from Rofi as well. -- **waybar horizontal and vertical,:** Take your pick during setup, easily toggleable from rofi as well. -here's what it looks like. +Here's what it looks like: ![New Nerdy Horizontal Waybar](Pictures/readme_assets/waybar_horizontal.webp) @@ -30,292 +97,405 @@ here's what it looks like. ![waybar_minimal](Pictures/readme_assets/waybar_minimal.webp) +--- + ## 🎨 Theming & Acknowledgments -A massive shoutout to [@Ubaidullah-Web-Dev](https://github.com/Ubaidullah-Web-Dev) for his amazing project that enables website theming on gecko based browsers like firefox! This configuration wouldn't have been possible without him. +A massive shoutout to [@Ubaidullah-Web-Dev](https://github.com/Ubaidullah-Web-Dev) for his +amazing project that enables website theming on Gecko-based browsers like Firefox! This +configuration wouldn't have been possible without him. -⭐ **Support the Developer:** If you like the look of this setup, please head over and drop a star on his repository: +⭐ **Support the Developer:** If you like the look of this setup, please head over and drop +a star on his repository: 👉 [MatugenFox on GitHub](https://github.com/Ubaidullah-Web-Dev/MatugenFox) -### There's also a brand new Dusky Control Center that acts as a system overview gui for settings and features, it's exhaustive in it's scope, almost anything you want to set/change can be done from this one stop shop intuitive gui app. I'll keep adding more quality of life features to it over time. +### Dusky Control Center + +There's also a brand new Dusky Control Center that acts as a system overview GUI for +settings and features. It's exhaustive in its scope — almost anything you want to +set or change can be done from this one-stop-shop intuitive GUI app. I'll keep adding more +quality-of-life features to it over time. ![Dusky Control Center](Pictures/readme_assets/dusky_control_center.webp) -This repository is the result of 8 months of tinkering/breaking/fixing and polishing. Its a labor of love designed to feel as easy to install as a "standard" distribution but with the raw power and minimalism of arch. **please consider starring ⭐ this repo** as a token of support. +--- ## ⚠️ Prerequisites & Hardware ### Filesystem -This setup is strictly optimized for **BTRFS file system format**. (should also work on ext4 but not recommanded) +This setup is strictly optimized for the **BTRFS filesystem**. (It should also work on +ext4, but that's not recommended.) -- **Why?** ZSTD compression, copy on write (CoW) to prevent data corruption, and you also get instant Snapshots. - +- **Why?** ZSTD compression, copy-on-write (CoW) to prevent data corruption, and you also + get instant snapshots. -### Hardware Config (Intel/Nvidia/AMD) +### Hardware config (Intel / NVIDIA / AMD) -The setup scripts are written to auto detect your hardware and set the appropriate environment variables but in case your hardware is not detected or has some issues, you're advised to configure the following files to set your environment variables. +The setup scripts are written to auto-detect your hardware and set the appropriate +environment variables. In case your hardware is not detected or has some issues, you're +advised to configure the following files to set your environment variables. -> [!Note] +> [!NOTE] > -> Configure the uwsm env files to set your gpu environment variables. +> Configure the UWSM env files to set your GPU environment variables. > -> 1. Open the files at ~/.config/uwsm/env and ~/.config/uwsm/env-hyprland +> 1. Open the files at `~/.config/uwsm/env` and `~/.config/uwsm/env-hyprland` > -> 2. Replace Intel/Nvidia/Amd -specific variables with your hardware equivalents. -> - +> 2. Replace Intel/NVIDIA/AMD-specific variables with your hardware equivalents. -### Dual Booting +### Dual booting - Compatible with Windows or other Linux distros. -- **Bootloader:** Defaults to `systemd-boot` for UEFI (boots up to 5s faster). Defaults to `GRUB` for BIOS. +- **Bootloader:** Defaults to `systemd-boot` for UEFI (boots up to 5s faster). Defaults to + `GRUB` for BIOS. +--- +## 💿 Installation -# Installation 💿 - -[Watch Video Tutorial][Watch Video Tutorial] +[**Watch the video tutorial**][Watch Video Tutorial] [Watch Video Tutorial]: https://youtu.be/OzeFAY_8T8Y -**Best for:** Users who already have a fresh, unconfigured Arch Linux installation with Hyprland, set up either via the archinstall script or through a manual install. If you have not installed yet, use the Arch ISO and ensure you select Btrfs as the filesystem and Hyprland as the window manager. +**Best for:** Users who already have a fresh, unconfigured Arch Linux installation with +Hyprland, set up either via the `archinstall` script or through a manual install. If you +have not installed yet, use the Arch ISO and ensure you select **Btrfs** as the filesystem +and **Hyprland** as the window manager. + +After installing Arch, boot into the OS and then run the steps below in the terminal. -after installing arch, boot into the os and then run this in the terminal. +> [!IMPORTANT] +> Step 1 force-checks-out tracked files directly into your home directory, **overwriting +> existing files with the same paths without prompting**. If you have configs you care +> about in `~/.config`, back them up first. +### 🆕 Dusky ISO is now available — it's an offline installer -# Dusky ISO is now available!!, its an offline installer. ``` https://drive.google.com/drive/folders/1P368khN1p-IfzWoaDnPyQNEcpkKBsOte?usp=sharing ``` +### Step 1: Clone dotfiles (bare repo method) -### Step 1: Clone Dotfiles (Bare Repo Method) +I use a bare git repository method to drop files exactly where they belong in your home +directory. -i use a bare git repository method to drop files exactly where they belong in your home directory. +Make sure you're connected to the internet and git is installed: -make sure your connected to the internet and git is installed, - -``` +```bash sudo pacman -Syu --needed git ``` +Clone the repo: -clone the repo -``` +```bash git clone --bare --depth 1 https://github.com/dusklinux/dusky.git $HOME/dusky ``` -deploy the files on your system. +Deploy the files on your system: ```bash git --git-dir=$HOME/dusky/ --work-tree=$HOME checkout -f ``` -> Note: -> -> This will immediately list a few errors at the top, but dont worry, that's expected behaviour, the errors will later go away on there own after matugen generates colors and cycles through a wallpaper. - +> [!NOTE] +> +> This will immediately list a few errors at the top, but don't worry — that's expected +> behaviour. The errors will go away on their own after Matugen generates colors and +> cycles through a wallpaper. ### Step 2: Run the Orchestra -Run the master script to install dependencies, themes, and services, this will take a while. because it sets up everything. You'll be promted to say yes/no during setup, so dont leave it running unattended. +Run the master script to install dependencies, themes, and services. This will take a +while, because it sets up everything. You'll be prompted to say yes/no during setup, so +don't leave it running unattended. ```bash ~/user_scripts/arch_setup_scripts/ORCHESTRA.sh ``` -## The Orchestra Script +--- + +## The Orchestra script -The `ORCHESTRA.sh` is a "conductor" that manages ~80 subscripts. +`ORCHESTRA.sh` is a "conductor" that manages ~80 subscripts. - **Smart:** It detects installed packages and skips them. - **Safe:** You can re-run it as many times as you like without breaking things. -- **Time:** Expect 30–60 minutes. We use `paru` to install a few AUR packages, and compiling from source takes time. Grab a coffee! +- **Time:** Expect 30–60 minutes. We use `paru` to install a few AUR packages, and + compiling from source takes time. Grab a coffee! +--- ## ⌨️ Usage & Keybinds -The steepest learning curve will be the keybinds. I have designed them to be intuitive, but feel free to change them in the config. +The steepest learning curve will be the keybinds. I have designed them to be intuitive, +but feel free to change them in the config. -> 💡 Pro Tip: +> [!TIP] > -> Press `CTRL + SHIFT + SPACE` to open the Keybinds Cheatsheet. You can click commands in this menu to run them directly! - +> Press `CTRL` + `SHIFT` + `SPACE` to open the Keybinds Cheatsheet. You can click commands +> in this menu to run them directly! -It's been tested to work on other arch based distros with hyprland installed (fresh installed) like catchyOS +It's been tested to work on other Arch-based distros with Hyprland installed (fresh +installed), like CachyOS. +--- ## 🔧 Troubleshooting If a script fails (which can happen on a rolling release distro): -1. **Don't Panic.** The scripts are modular. The rest of the system usually installs fine. - -2. **Check the Output.** Identify which subscript failed (located in `$HOME/user_scripts/setup_scripts/scripts/`). - -3. **Run Manually.** You can try running that specific subscript individually. - -4. **AI Help.** Copy the script content and the error message into ChatGPT/Gemini. It can usually pinpoint the exact issue (missing dependency, changed package name, etc.). - +1. **Don't panic.** The scripts are modular. The rest of the system usually installs fine. + +2. **Check the output.** Identify which subscript failed. They're located in + `~/user_scripts/arch_setup_scripts/scripts/`. + +3. **Run it manually.** You can try running that specific subscript individually — this + usually gives a much clearer error than the full run does. + +4. **Re-run the Orchestra.** It's idempotent and safe to re-run: + `~/user_scripts/arch_setup_scripts/ORCHESTRA.sh` + +5. **AI help.** Copy the script content and the error message into ChatGPT/Gemini. It can + usually pinpoint the exact issue (missing dependency, changed package name, etc.). + +6. **Still stuck?** Ask on [Discord][discord], or + [open a bug report](https://github.com/dusklinux/dusky/issues/new?template=bug_report.yml). + Please include your GPU vendor, filesystem, and install method — those three things + resolve most reports. + +--- -## overview +## Overview -Note : i've purposely decided to not use quickshell for anything in the interest of keeping this as light weight as possible, Quickshell can quickly add to ram and slow down your system, therefore everything is user friendly Tui to keep it snappy and lightweight while delivering on A WHOLE HOST OF FEATURES. Read below for most features. +> [!NOTE] +> I've purposely decided not to use Quickshell for anything, in the interest of keeping +> this as lightweight as possible. Quickshell can quickly add to RAM and slow down your +> system. Therefore everything is user-friendly TUI, to keep it snappy and lightweight +> while delivering a whole host of features. Read below for most of them. -**utilities** +### Utilities -- Music Recognition - allows you to look up what music is playing. +- **Music recognition** — look up what music is playing. -- Circle to search type feature. uses Google lens. +- **Circle-to-search** type feature, using Google Lens. -- Tui for chaining your hyprland's appearience like gaps, shadow color, blur strength, opacity strength and a lottt more!! +- **TUI for changing Hyprland's appearance** — gaps, shadow color, blur strength, opacity + strength and a lot more. -- Ai llm local infrense using ollama side bar (terminal, incredilby resource efficient) +- **Local AI LLM inference** via an Ollama sidebar (terminal-based, incredibly resource + efficient). -- keybind TUI setter that auto checks for conflicts and unbinds any existing keybind in the default hyrland keybind.conf +- **Keybind TUI setter** that auto-checks for conflicts and unbinds any existing keybind in + the default Hyprland `keybinds.conf`. -- Easily switch Swaync's side to either lift or right. +- **Easily switch SwayNC's side** to either left or right. -- airmon wifi script for wifi testing/password cracking - (only use on access points that you own, i'm not legally responsible if you use it for nefarious purposes) -- live disk i/o monitoring, to allow you to see live read/write disk speed during copying and infer if copying has actually finsihed, useful for flashdrives, external drives. +- **`airmon` wifi script** for wifi testing / password cracking. + ⚠️ Only use this on access points that you own. I'm not legally responsible if you use it + for nefarious purposes — see [SECURITY.md](.github/SECURITY.md). -- quick audio input/output switch with a keybind, eg if you have bluetooth headphones connected, you can quicly switch to speakers without disconnecting. +- **Live disk I/O monitoring** — see live read/write disk speed during copying, and infer + whether copying has actually finished. Useful for flash drives and external drives. -- mono/sterio audio toggling. +- **Quick audio input/output switching** with a keybind. If you have Bluetooth headphones + connected, you can quickly switch to speakers without disconnecting. -- also supports touchpad gestures for volume/brightess, locking the screen, invoking swaync, pause/play, muting.(requires a laptop or a touchpad for pc) +- **Mono/stereo audio toggling.** -- battery notifier for laptops, you can customize it to show notifications at certain levels. +- **Touchpad gestures** for volume/brightness, locking the screen, invoking SwayNC, + play/pause, and muting. (Requires a laptop or a touchpad for PC.) -- Togglable power saver mode. +- **Battery notifier** for laptops — customize it to show notifications at certain levels. -- system clean up (cache purge)- removes unwanted files to reclaim storage. +- **Toggleable power saver mode.** -- usb sounds , get notified when usb devices are plugged/unplugged. +- **System cleanup (cache purge)** — removes unwanted files to reclaim storage. -- FTP server auto setup. +- **USB sounds** — get notified when USB devices are plugged in or unplugged. -- Tailscale auto setup. +- **FTP server auto setup.** -- Openssh auto setup. with or without tailscale. +- **Tailscale auto setup.** -- auto warp- cloudflaire setup and toggleale right from rofi. +- **OpenSSH auto setup**, with or without Tailscale. -- Vnc setup for iphones (wired) +- **Cloudflare WARP auto setup**, toggleable right from Rofi. -- dynamic frantional scalling script so you can scale your display with a keybind. +- **VNC setup for iPhones** (wired). -- toggle window transparancy, blur and shadow with a single keybind. +- **Dynamic fractional scaling script** so you can scale your display with a keybind. -- hypridle tui configuration. +- **Toggle window transparency, blur and shadow** with a single keybind. -- wifi connecting script for setup at ~/user_scripts/network_manager/nmcli_wifi.sh +- **Hypridle TUI configuration.** -- Sysbench benchmarking script. +- **WiFi connection script** at `~/user_scripts/network_manager/dusky_network.sh` (with a + TUI at `tui_dusky_network.py`). -- color picker +- **Sysbench benchmarking script.** -- neovim configured, you could also use your own later on. or install lazyvim or any another neovim rice +- **Color picker.** +- **Neovim, preconfigured.** You can also use your own later on, or install LazyVim or any + other Neovim rice. -- github repo integration so you can easily create your own repo to backup all files, this uses bare repo so your specific existing files, listed in ~/.git_dusky_list will backup to github, you can add more files/remove existing ones from this text file. +- **GitHub repo integration** so you can easily create your own repo to back up all files. + This uses a bare repo, so your specific existing files — listed in `~/.git_dusky_list` — + will back up to GitHub. You can add more files or remove existing ones from that text + file. -- btrfs system compression ratio - scans your os files to see how much space zstd compression is saving you. +- **BTRFS compression ratio** — scans your OS files to see how much space ZSTD compression + is saving you. -- drive manager, easily lock/unlock encrypted drives from the terminal using "unlock media or lock media", it automaticlaly mounts your drives at a specified path, also unmounts when you lock it. This requires you to first configure the ~/user_scripts/drives/drive_manager.sh script with your drives' uuid. +- **Drive manager** — easily lock/unlock encrypted drives from the terminal using + `unlock media` or `lock media`. It automatically mounts your drives at a specified path, + and unmounts when you lock it. This requires you to first configure + `~/user_scripts/drives/drive_manager/drives.toml` with your drives' UUIDs. -- ntfs drives have a tendency to not unlock if the drive had previously been disconnected without unmounting first, because of corrupted metadata, i've a script that fixes this. ntfs_fix.sh +- **NTFS fix** — NTFS drives have a tendency to not unlock if the drive was previously + disconnected without unmounting first, because of corrupted metadata. There's a script + that fixes this: `~/user_scripts/drives/ntfs_fix.sh`. -RoFI menus. +### Rofi menus - Emoji - Calculator -- Matugen Theme switcher. -- Animation switcher. -- Power menu. +- Matugen theme switcher +- Animation switcher +- Power menu - Clipboard - Wallpaper selector -- Shader menu. -- System menu. +- Shader menu +- System menu + +...and a lot more that would take forever to list. Trust me, these dotfiles are the shit — +try 'em out. + +### GUI keybind-invokable sliders + +- Volume control +- Brightness control +- Nightlight / hyprsunset intensity + +### Speech + +**Speech to text** + +- Whisper — for CPU +- Parakeet — for NVIDIA GPUs (might also work on AMD, not sure) + +**Text to speech** + +- Kokoro, for both CPU and GPU -and a lot more that would take forever to list, trust me these dotfiles are the shit! try em out. +### Miscellaneous -GUI keybind invokable sliders for: -- Volume control -- Brightness control -- Nightlight/hyprsunset intensity. +- **Mechanical keypress sounds** — toggleable with a keybind or from Rofi. +- **Wlogout** is drawn using a dynamic script that respects your fractional scaling. -Speech to text -- Whisper - for cpu -or -- Parakeet - for nvidia gpus. might also work on Amd (not sure) +--- -text to speech -- kokoro for both cpu and gpu +## Performance and system -- mechanical keypress sounds -togglalble with a keybind or from rofi. +- **Lightweight** — ~900 MB RAM usage and ~5 GB disk usage, fully configured. -- Wlogout is drawn using a dynamic script that respects your frational scaling. +- **ZSTD & ZRAM** — compression enabled by default to save storage and triple your + effective RAM (great for low-spec machines). +- **Native optimization** — AUR helpers configured to build with CPU-native flags (up to + 20% performance boost). -**performance and system** +- **UWSM environment** — optimized specifically for Hyprland. -- **light weight**, ~900MB RAM usage and ~5GB disk usage (fully configured). - -- **ZSTD & ZRAM:** Compression enabled by default to save storage and triple your effective RAM (great for low-spec machines). - -- **Native Optimization:** AUR helpers configured to build with CPU-native flags (up to 20% performance boost). - +## Graphics and gaming -- **UWSM Environment:** Optimized specifically for Hyprland. - +- **Fluid animations** — tuned physics and momentum for a "liquid" feel. I've spent days + fine-tuning this. -**Graphics & Gaming** +- **GPU passthrough guide** — zero latency (native performance) for dual-GPU setups using + Looking Glass. -- **Fluid Animations:** Tuned physics and momentum for a "liquid" feel, I've spent days fine tuning this. - -- **GPU Passthrough Guide:** Zero latency (native performance) for dual-GPU setups using Looking Glass. - -- **Instant Shaders:** Switch visual shaders instantly via Rofi. - -- **Android Support:** Automated Waydroid installer script. - +- **Instant shaders** — switch visual shaders instantly via Rofi. -**Usability & Theming** +- **Android support** — automated Waydroid installer script. -- **Universal Theming:** `Matugen` powers a unified Light/Dark mode across the system. - -- **Dual Workflow:** Designed for both GUI-centric (mouse) and Terminal-centric (keyboard) users. - -- **Accessibility:** Text-to-Speech (TTS) and Speech-to-Text (STT) capabilities (hardware dependent). - -- **Keybind Cheatsheet:** Press `CTRL` + `SHIFT` + `?` anytime to see your controls. - +- **FPS limiter** and gaming package setup. +## Usability and theming + +- **Universal theming** — Matugen powers a unified light/dark mode across the system. + +- **Dual workflow** — designed for both GUI-centric (mouse) and terminal-centric + (keyboard) users. + +- **Accessibility** — text-to-speech (TTS) and speech-to-text (STT) capabilities + (hardware dependent). + +- **Keybind cheatsheet** — press `CTRL` + `SHIFT` + `SPACE` anytime to see your controls. + +---
-Enjoy the experience! +**Enjoy the experience!** -If you run into issues, check the detailed Obsidian notes included in the repo (~2MB). +If you run into issues, check the detailed Obsidian notes included in the repo (~2 MB) at +`~/Documents/pensive/`.
+--- + +## 🤝 Contributing + +Contributions are very welcome — bug reports, scripts, docs fixes, typo corrections, and +testing on hardware nobody else has. + +- **[Contributing guide](.github/CONTRIBUTING.md)** — development setup, shell and Python + conventions, how to add a setup subscript. **Read the development setup section first:** + Dusky deploys via a bare repo into `$HOME`, so editing it safely is not obvious. +- **[Code of Conduct](.github/CODE_OF_CONDUCT.md)** +- **[Security policy](.github/SECURITY.md)** — including what you should know about the + privileged scripts, networking helpers, and wireless tooling before installing. +- **[Support](.github/SUPPORT.md)** — where to ask questions. +- **[Changelog](CHANGELOG.md)** +| I want to... | Go here | +|---|---| +| Report a bug | [Bug report](https://github.com/dusklinux/dusky/issues/new?template=bug_report.yml) | +| Request a feature | [Feature request](https://github.com/dusklinux/dusky/issues/new?template=feature_request.yml) | +| Ask a question | [Discord][discord] | +| Report a vulnerability | [Privately, here](https://github.com/dusklinux/dusky/security/advisories/new) | -# Acknowledgments: -Thank you to all the Contributors! +--- -sddm is a modified version of the SilentSDDM project by @uiriansan (this is a great project! Kindly star it on github) +## Acknowledgments -[SilentSDDM by uiriansan][repo_linkk] +Thank you to all the contributors! + +- **SDDM** is a modified version of the SilentSDDM project by + [@uiriansan](https://github.com/uiriansan) — this is a great project, kindly star it on + GitHub: [SilentSDDM][repo_linkk] + +- **Firefox theming** is powered by + [MatugenFox](https://github.com/Ubaidullah-Web-Dev/MatugenFox) by + [@Ubaidullah-Web-Dev](https://github.com/Ubaidullah-Web-Dev). [repo_linkk]: https://github.com/uiriansan/SilentSDDM/ +## License + +Released under the [MIT License](LICENSE). + +
+ +If Dusky is useful to you, **a star ⭐ genuinely helps.** + +
From 817e026f67ee11002a141a90d3b7ec6559f4d15a Mon Sep 17 00:00:00 2001 From: Ainsley Woo <125954904+Kantosaurus@users.noreply.github.com> Date: Tue, 28 Jul 2026 17:20:03 +0800 Subject: [PATCH 5/5] fix: correct if/fi mismatch that prevented dusky_tui from parsing A conditional block was closed with } instead of fi, so the script failed to parse and could not run. Replace the } with fi. --- .../bash/for_equal_assignment_delimiter_only/dusky_tui_4.3.0.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_scripts/dusky_tui/bash/for_equal_assignment_delimiter_only/dusky_tui_4.3.0.sh b/user_scripts/dusky_tui/bash/for_equal_assignment_delimiter_only/dusky_tui_4.3.0.sh index 044864f70..cfd3f25a8 100755 --- a/user_scripts/dusky_tui/bash/for_equal_assignment_delimiter_only/dusky_tui_4.3.0.sh +++ b/user_scripts/dusky_tui/bash/for_equal_assignment_delimiter_only/dusky_tui_4.3.0.sh @@ -825,7 +825,7 @@ write_value_to_file() { _TMPMODE="" set_status "Refusing empty write." return 1 - } + fi commit_tmpfile || { rm -f -- "$_TMPFILE" 2>/dev/null || :