While running nixos-rebuild boot, my laptop suffered a hard crash from running out of battery power. I rebooted the machine and reran nixos-rebuild boot, which seemed to work fine.
Could there now be some leftovers from the first nixos-rebuild run? What could these be: leftovers that would be removed by garbage collection, stale build sandboxes, which perhaps wouldn’t be removed by garbage collection, or anything else? How can I remove any leftovers?
I’m using NixOS 25.05 with btrfs as the file system.
There shouldn’t be any leftovers since Nix is atomic. At worst, if the power loss caused some file system corruption, some Nix store paths may be corrupted. You can check and automatically repair with:
sudo nix-store --verify --check-contents --repair
(this may download or rebuild some store paths if they don’t match the expected hashes)
leftovers that would be removed by garbage collection
I don’t think a garbage collection is needed: if you didn’t update the channel, since NixOS is (almost entirely) reproducible, you will end up with the same derivations as before.
stale build sandboxes
Those are in /tmp, so they will be removed sooner or later anyway. If you have /tmp on tmpfs they have already be cleared.
Something else that could be corrupted is the bootloader, if you lost power while running the install-bootloader script. But that should be reproducible as well, so again, it shouldn’t be an issue.
The only issues I could see happening from this is maybe store corruption, which you can check for with the command above, and bootloader misconfiguration, which should be fixed as soon as you run nixos-rebuild boot again. (Though that would only happen with exceptionally poor timing, and the fact that you booted successfully afterward pretty much means this didn’t happen)
Well, NixOS being atomic doesn’t mean that there can’t be any leftovers. A derivation cannot be created atomically in the store, as multiple files need to be created. Only the final switch to the new generation is atomic, being a change of a symbolic link. Therefore, there may well be partial derivations in the store. If derivations already have their final directory names while being created, this would mean having an inconsistent store. If they have temporary directory names while being created, the store wouldn’t be inconsistent, but there would still be files that don’t belong there. I suppose that Nix follows the latter approach, so that the store stays consistent, but I still wouldn’t like to have stale data there.
But they are not marked as finished in the nix DB, so if that given path is “requested” nix knows it’s broken. Nix would also remove it on a store repair.
The biggest problem I have seen so far is files truncated to zero size, because they have been opened for reading at the wrong point in time.
It definitely can happen with btrfs, I have experienced this and it’s really frustrating.
There was at one point some work on improving this by adding an option called fsync-store-paths, but I don’t think there’s been any progress on the topic since last year.
Kind of by definition there cannot. NixOS activation is atomic, so either your switch was successful, or it was not. If it was successful, leftovers from the previous generation will be cleaned by nix-collect-garbage. If if was not successful, leftovers from the next generation will be cleaned by nix-collect-garbage (or simply deployed next time you attempt a switch).
Partial runs of the activation script can result in “leftovers”, but next time you boot those will be overwritten/used, so that’s not really a leftover either. There could be bugs in the activation script, but those would cause issues with normal system use, too.
If the power failure caused file corruption, store repair fixes that.
I’ve seen the occasional person get into states where the nix command fails to run, however, so if you get unlucky with corruption you may need to manually clear nix caches, too. I’m not 100% certain what causes those kinds of issues, but they’re not inherent failures of the design, more accidental reliance on state.
I misread your question somewhat, you’re clearly asking about nixos-rebuild boot, which doesn’t even involve the activation script. Your question is whether a nix build leaves any debris.
Which, yeah, that’s a reasonable thing to ask. Obviously the builds themselves are not atomic, so at the very least a temporary directory must exist at some point, even if it is cleaned up during normal system use and is otherwise inert.
In theory, you’d think so. In reality, not quite. After the derivation finishes, nix has to copy it out of the build sandbox into the actual nix store, and that copy is not necessarily instantaneous. This is one of the reasons the nix db exists. Store paths are marked “valid” in the db after they’re fully written.
This is exactly the kind of problem I was referring to. You may do all the building in a sandbox outside of the store, but at least you must copy the result to the store, and this cannot be atomic, as multiple files are involved. Well, it could be atomic if the sandbox would be on the same device as the store, as you could use an atomic move then, but I understand that the sandbox is under /tmp, which may well be on a different device.
If there is a directory within the store that is not marked as valid in the database, will it be deleted by nix-store --verify --repair?
I don’t know off the top of my head whether the default behavior is to delete it, but it will certainly print output regarding such a path if one exists and it does not delete it.
If the path is available on the binary cache it will be fetched again. If it was built locally and its input derivations are available or if it was a fixed-output derivation (like fetchurl) it will be rebuilt from scratch. If the inputs are no longer available or the build fails, then the repair operation will fail.
If nix-store --verify --check-contents --repair succeeds you are 100% sure the Nix store is intact.
Source: I have a laptop with a completely drained battery.
It’s strange then that, after an interrupted GNOME installation, the following GNOME installation emitted warnings that a later GNOME installation conducted after a complete deletion of GNOME did not. See Error message related to `*.desktop` files during GNOME installation.