headless home, and fixed legoals sleep
This commit is contained in:
+31
-1
@@ -15,4 +15,34 @@ Changes (`hosts/legolas/hardware-configuration.nix`):
|
||||
- Removed the no-op `d3cold_allowed` rule and the broken rescan service.
|
||||
- Added a correct runtime-PM-off udev rule on both the NVMe endpoint (`0000:6e:00.0`) and its parent root port (`0000:00:1d.0`), keeping the PCIe wakeup disable.
|
||||
|
||||
Note: runtime PM was already off on the endpoint (`power/control=on`); that alone never fixed the crash because system suspend uses a separate code path. Verify after rebuild that the cmdline has `mem_sleep_default=s2idle` (the old running generation showed a stale duplicate `deep`).
|
||||
Note: runtime PM was already off on the endpoint (`power/control=on`); that alone never fixed the crash because system suspend uses a separate code path. Verify after rebuild that the cmdline has `mem_sleep_default=s2idle` (the running generation showed a stale duplicate `deep`).
|
||||
|
||||
## Headless home-manager configs (galadriel, elros, elrond)
|
||||
|
||||
Added minimal home-manager configs for `gunalx` and `root` on headless hosts. These skip all GUI/desktop modules (niri, stylix, foot, noctalia, etc.) and keep only CLI tools: bash (with sops AI keys), git, nixvim (full config reused), opencode, atuin, sshconfig, sops.
|
||||
|
||||
Files:
|
||||
- `home/gunalx-headless.nix` — gunalx's minimal config, same module set as `gunalx.nix` minus all GUI imports.
|
||||
- `home/root.nix` — identical CLI stack, explicitly sets `home.username`/`home.homeDirectory` to root.
|
||||
- `home/sops.nix` — parameterized age key paths to use `config.home.homeDirectory` so both users work without duplication.
|
||||
- `home/sshconfig.nix` — removed `ssh-askpass-fullscreen` (unwired GUI dependency, was dead weight).
|
||||
- `flake.nix` — added `headlessHmModules` let binding (shared by all three hosts) wiring `home-manager.users.gunalx` + `home-manager.users.root`.
|
||||
|
||||
Manual step: root needs the sops age key at `/root/.config/sops/age/key.txt` (or SSH key at `/root/.ssh/nixos`) to decrypt AI API secrets. `age.generateKey = true` will create a new key, but it won't match the encrypted secrets — copy gunalx's age key to root's path, or re-encrypt the secrets with root's age public key.
|
||||
|
||||
## galadriel: kernel 7.0 EOL
|
||||
|
||||
Linux 7.0 was removed from nixpkgs (EOL). `pkgs.zfs` (stable) is now 2.4.2, same version previously pulled from unstable. Switched `boot.kernelPackages` to the default (6.18) and `boot.zfs.package` to `pkgs.zfs`. No pool compatibility concern since ZFS version is unchanged.
|
||||
|
||||
## legolas: lid-close still killing the NVMe — stale `deep` + logind suspend
|
||||
|
||||
Root cause of the recurring "SSD dies when lid closed": the *booted* generation carried a duplicate `mem_sleep_default=deep` after `mem_sleep_default=s2idle` (last wins), so `/sys/power/mem_sleep` was `s2idle [deep]` — every suspend went to S3. The source config only had `s2idle`; the stale param lived in the old generation. ACPI advertises S3 (`supports S0 S3 S4 S5`) but S3 is broken for the Phison E21 on this Skylake-era Intel platform, so only s0/s2idle is reliable. Separately, `HandleLidSwitch` was unset → defaulted to `suspend`, which was the actual lid-close trigger.
|
||||
|
||||
Changes (`hosts/legolas/hardware-configuration.nix`):
|
||||
- `services.logind.lidSwitch`/`lidSwitchExternalPower`/`lidSwitchDocked` = `ignore`. Lid close no longer suspends; niri's `switch-events` still locks via noctalia, so the laptop stays on (RAM powered) but can't enter the S3 path.
|
||||
- `systemd.services.force-s2idle` writes `s2idle` to `/sys/power/mem_sleep` at boot — guarantees the active mode is s2idle even if a future cmdline carries a stray `deep`.
|
||||
- Suspend (s2idle) remains available via `systemctl suspend`; hibernation stays disabled.
|
||||
|
||||
Also fixed `home/niri.nix` lid-close command from the undocumented `lockScreen lock` to the v5-canonical `session lock` (matching the `Mod+M` binding).
|
||||
|
||||
Verify after rebuild+reboot: `/proc/cmdline` has no `deep`, and `/sys/power/mem_sleep` shows `[s2idle] deep`.
|
||||
|
||||
@@ -63,6 +63,36 @@
|
||||
}@inputs:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
|
||||
headlessHmModules = [
|
||||
home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager.backupFileExtension = "bac";
|
||||
home-manager.extraSpecialArgs = { inherit inputs; };
|
||||
home-manager.sharedModules = [
|
||||
inputs.sops-nix.homeManagerModules.sops
|
||||
inputs.nixvim.homeModules.nixvim
|
||||
];
|
||||
home-manager.users.gunalx = import ./home/gunalx-headless.nix;
|
||||
home-manager.users.root = import ./home/root.nix;
|
||||
}
|
||||
{
|
||||
home-manager.users.gunalx = {
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
nixpkgs.overlays = [
|
||||
self.overlays.custom
|
||||
self.overlays.unstable
|
||||
];
|
||||
};
|
||||
home-manager.users.root = {
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
nixpkgs.overlays = [
|
||||
self.overlays.custom
|
||||
self.overlays.unstable
|
||||
];
|
||||
};
|
||||
}
|
||||
];
|
||||
in
|
||||
{
|
||||
packages.${system} =
|
||||
@@ -245,7 +275,7 @@
|
||||
|
||||
lanzaboote.nixosModules.lanzaboote
|
||||
|
||||
];
|
||||
] ++ headlessHmModules;
|
||||
};
|
||||
|
||||
# elros
|
||||
@@ -263,7 +293,7 @@
|
||||
./hosts/elros/configuration.nix
|
||||
sops-nix.nixosModules.sops
|
||||
lanzaboote.nixosModules.lanzaboote
|
||||
];
|
||||
] ++ headlessHmModules;
|
||||
};
|
||||
|
||||
# elrond
|
||||
@@ -281,7 +311,7 @@
|
||||
./hosts/elrond/configuration.nix
|
||||
sops-nix.nixosModules.sops
|
||||
lanzaboote.nixosModules.lanzaboote
|
||||
];
|
||||
] ++ headlessHmModules;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
./sshconfig.nix
|
||||
./atuin.nix
|
||||
./git.nix
|
||||
./bash.nix
|
||||
|
||||
./opencode.nix
|
||||
./nixvim.nix
|
||||
|
||||
inputs.sops-nix.homeManagerModules.sops
|
||||
./sops.nix
|
||||
];
|
||||
|
||||
programs.nix-index = {
|
||||
enableBashIntegration = true;
|
||||
enable = true;
|
||||
};
|
||||
|
||||
home.packages = with pkgs; [
|
||||
comma
|
||||
];
|
||||
|
||||
home.stateVersion = "25.05";
|
||||
}
|
||||
+1
-1
@@ -162,7 +162,7 @@ in
|
||||
|
||||
# Switch events for lid open/close
|
||||
switch-events = {
|
||||
lid-close.action.spawn = noctalia "lockScreen lock";
|
||||
lid-close.action.spawn = noctalia "session lock";
|
||||
tablet-mode-on.action.spawn = [
|
||||
"bash"
|
||||
"-c"
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
./sshconfig.nix
|
||||
./atuin.nix
|
||||
./git.nix
|
||||
./bash.nix
|
||||
|
||||
./opencode.nix
|
||||
./nixvim.nix
|
||||
|
||||
inputs.sops-nix.homeManagerModules.sops
|
||||
./sops.nix
|
||||
];
|
||||
|
||||
programs.nix-index = {
|
||||
enableBashIntegration = true;
|
||||
enable = true;
|
||||
};
|
||||
|
||||
home.packages = with pkgs; [
|
||||
comma
|
||||
];
|
||||
|
||||
home.username = "root";
|
||||
home.homeDirectory = "/root";
|
||||
home.stateVersion = "25.05";
|
||||
}
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
sops = {
|
||||
defaultSopsFile = ../secrets/secrets.yaml;
|
||||
validateSopsFiles = false;
|
||||
age.sshKeyPaths = [ "/home/gunalx/.ssh/nixos" ];
|
||||
age.keyFile = "/home/gunalx/.config/sops/age/key.txt";
|
||||
age.sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/nixos" ];
|
||||
age.keyFile = "${config.home.homeDirectory}/.config/sops/age/key.txt";
|
||||
age.generateKey = true;
|
||||
# This is the actual specification of the secrets.
|
||||
#secrets."myservice/my_subdir/my_secret" = {};
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
home.packages = with pkgs; [
|
||||
openssh
|
||||
ssh-askpass-fullscreen
|
||||
sshfs
|
||||
];
|
||||
|
||||
|
||||
@@ -23,9 +23,7 @@
|
||||
"sd_mod"
|
||||
];
|
||||
|
||||
# unstable zfs and linux because we needed zfs 2.4.2 for linux 7.0
|
||||
boot.kernelPackages = pkgs.unstable.linuxPackages_7_0; # migth need to bump down if zfs compat breaks.
|
||||
boot.zfs.package = pkgs.unstable.zfs; # think this was the correct way
|
||||
boot.zfs.package = pkgs.zfs;
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
@@ -12,13 +12,18 @@
|
||||
#boot.kernelPackages = pkgs.linuxPackages_zen;
|
||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||
|
||||
boot.kernelParams = [
|
||||
boot.kernelParams = lib.mkForce [
|
||||
# s2idle (modern standby) instead of deep (S3): the Phison E21 NVMe
|
||||
# controller (Corsair MP600 ELITE) hangs on resume from the D3 transition
|
||||
# that S3 forces. s2idle avoids that path.
|
||||
"mem_sleep_default=s2idle"
|
||||
"nvme_core.default_ps_max_latency_us=0"
|
||||
"pcie_aspm=off"
|
||||
|
||||
# from hardware config we are overriding away the deep sleep of.
|
||||
"i915.enable_guc=2"
|
||||
"i915.enable_fbc=1"
|
||||
"i915.enable_psr=2"
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
@@ -70,6 +75,17 @@
|
||||
};
|
||||
};
|
||||
|
||||
# Lid close must NOT suspend. The Phison E21 NVMe hangs on resume from any
|
||||
# system suspend, and logind defaults to HandleLidSwitch=suspend (the trigger
|
||||
# that kills the drive). Ignore the lid at the logind level; niri's
|
||||
# switch-events handler still locks the session via noctalia, so the laptop
|
||||
# stays on (RAM powered, s0idle) but never enters the death path.
|
||||
services.logind = {
|
||||
lidSwitch = "ignore";
|
||||
lidSwitchExternalPower = "ignore";
|
||||
lidSwitchDocked = "ignore";
|
||||
};
|
||||
|
||||
# Keep runtime PM off on the NVMe controller and its parent root port, and
|
||||
# disable PCIe wakeup events. (The previous d3cold_allowed rule was a no-op:
|
||||
# that sysfs attribute doesn't exist on this Phison endpoint or its root port.)
|
||||
|
||||
Reference in New Issue
Block a user