I’d like to know the size of the complete /nix/store to decide whether to do GC when it gets over a threshold.
Currently I’m reading the nix DB to do that:
sqlite3 'file:/nix/var/nix/db/db.sqlite?readonly=true&immutable=true' 'SELECT SUM(narSize) FROM ValidPaths'
That works, but of course that’s not a supported API, and I’m ignoring the lock which I’m sure could lead to errors (maybe it would be possible to run this with the permissions and in the mount namespace of the nix daemon?).
The manual suggests this, but it’s very inefficient:
· Show the size of the entire Nix store:
| # nix path-info --json --all | jq 'map(.narSize) | add'
| 49812020936
Is there a way to do the equivalent of the sqlite query through the nix CLI or in the nix language?
If not, would there be interest in adding such a feature?
You could just do a blunt du -sh /nix/store. That will give you the disk space consumed by the nix store, in a human readable fashion, with a summary at the bottom.
Yes of course, but that’s also not efficient, it has to look at all the files in the store, except maybe on BtrFS, its similar to the nix path-info command.
It might also be possible to set up quotas on the filesystem to track the disk usage of /nix/store separately from the rest, but it’s quite complicated.
This actually makes me think that using the narSize probably does not take the nix store hardlink optimizations into account, so it could be an overestimate. Not sure if that’s tracked in the DB as well.
Exactly because ncdu takes such a long time on /nix, I do the opposite: run ncdu --exclude /nix -x / to get the size of everything but /nix in my root partition, and then subtract that from the total space used on my root partition (obtained by e.g. df -h /)
For a helpful suggestion that wasn’t mentioned in the original post, put /nix/store in a separate partition from everything else and then findmnt -b -n -o USED /nix/store will print the number you want (plus or minus filesystem overhead).
Bonus: all the other partitions can be mounted nosuid.
Hehe good news, in case you want to have that mount-flag on all filesystems.
/nix/store does not contain suid binaries, as nix build runs unprivileged, therefor can’t set suid - in addition it would cause security issues, such as when eject which is a suid binary contains a suid-exploiting CVE, you would have to remove the binary from your immutable store in order to fix the security issue.
Instead you have the option security.wrappers which bundles all required binaries in a tmpfs under /run/wrappers/bin - which is populated by the systemd service suid-sgid-wrappers.service which just stars a shell-script that runs basically cp + chmod from the nix store into the tmpfs.