Open LordMZTE opened 5 months ago
This is hard to support because the NAR file format puts the size of the file before its contents. So if we can't rely on the file size reported by lstat()
, we would have to read the entire file into memory first, which would be a problem for supporting large files.
I see. Here's a few thoughts I have on how this could theoretically be solved, note that I don't really know how feasible these are given that I'm not familiar with how Nix works internally:
Some things to consider:
/dev/random
? Should we have a hard limit on how large a file can be? Should we have this limit only for files that report a zero-size?Triaged in Nix team meeting:
@roberth: we could special-case the 0. if the size is reported as 0, we could still try reading it and buffer it.
/proc
)@edolstra: we used to buffer essentially entire files in memory, but that simply doesn't scale
This wouldn't work if the NAR file is created in a streaming fashion.
@Ericson2314: It is created in a streaming fashion, we wish to use constant space and often create NARs directly into a sink like a pipe or socket.
This mismatch between actual file size and reported file size is considered absolutely legal under Linux (citation needed)
@Ericson2314: We would love to see that citation :)
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/2024-05-15-nix-team-meeting-minutes-146/45491/1
Describe the bug
When a file is copied to the Nix store from a local path, and an
fstat
on that file returns a size of 0, an empty file will end up in the Nix store even though the file may yield more data when read.This mismatch between actual file size and reported file size is considered absolutely legal under Linux (citation needed). Nix should handle it correctly.
Steps To Reproduce
The filesystem I have used to reproduce this is my own FUSE3-based filesystem, confgenfs (which behaves like this because another implementation is not possible - files may be different every time they're read and are generated on-demand). I also recall observing this behavior with other (typically FUSE-based) filesystems, but did not find another one while writing this issue.
Expected behavior
The file is read until the
read
(or whatever syscall) returns a length of 0 instead of stopping at the length returned byfstat
, causing the file to be correctly copied to the store.nix-env --version
output nix-env (Nix) 2.22.0Additional context
Nix will actually
open
the file as reported by the filesystem in this case, but will not read all data from it.Priorities
Add :+1: to issues you find important.