Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/lib/make-ext4-fs: fall back to resize2fs -M if exact resize fails #79368

Merged
merged 1 commit into from Feb 9, 2020

Conversation

sorki
Copy link
Member

@sorki sorki commented Feb 6, 2020

Workaround to fix resize2fs failures on armv7l and aarch64. I would drop the exact resizing but it seems to work fine on x86 and might affect image reproducibility. There's not much to be gained by aggressive resizing (other than reproducibility) due to zstd compression anyway. Side-note: when using sdImage the image is by default compressed again with bz2 which only causes it grow a little.

See also

Motivation for this change
Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@samueldr
Copy link
Member

samueldr commented Feb 7, 2020

I'm now questioning the old code path. Shouldn't we prefer always using -M? Did you look it into it enough to know the drawbacks?

If it's because it would end up bigger, it looks like we could run it twice or thrice to get it a bit more snug, but at the expense of performance. Since we're now bzipping the resulting image, it won't affect the hydra build. The main issue we may have is small SD devices and small eMMCs, but that should still be under 4GiB, and certainly far under 8GiB.

@sorki
Copy link
Member Author

sorki commented Feb 7, 2020

I've tried running it 10 times in a loop (according to launchpad comment) but only the first iteration had any effect.

@samueldr
Copy link
Member

samueldr commented Feb 7, 2020

Right, but comparing our current resize thing, with -M do you know what drawbacks there may be?

@sorki
Copy link
Member Author

sorki commented Feb 8, 2020

Not aware of any drawbacks but I'm no expert when it comes to e2fsprogs. It could affect reproducibility but it's improbable as the result mkfs + file copies should be deterministic.

echo "Failed, resizing to minimum allowed by resize2fs"
fsck.ext4 -y -f $img
resize2fs $img -M
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer only resize once, with -M, rather than fail once, then doing it with -M.

This also means we might be able to remove some dead code around here, which is good, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm all for it when it comes to deleting redundant code, updated with snuggly resize dropped.

@samueldr
Copy link
Member

samueldr commented Feb 9, 2020

This increases the partition size from 2.0 GiB to 2.4GiB, but considering it only adds 1MiB to the final build artifact, it's not an issue. We were not targeting 2.0GiB to fit on a small SD card, but only for hydra.

@samueldr samueldr merged commit cebb0b4 into NixOS:master Feb 9, 2020
ztzg pushed a commit to ztzg/nixpkgs that referenced this pull request May 31, 2021
The root filesystem resizing step, `resize2fs -M', does not provide any
control over the amount of slack left in the result.  It can produce an
arbitrarily tight fit, depending on how well the payload aligns with
ext4 data structures.

This is problematic, as NixOS must create a few files and directories
during its first boot, before the root is enlarged to match the size of
the containing SD card.

An overly tight fit can cause failures in the first stage:

    mkdir: can't create directory '/mnt-root/proc': No space left on device

or in the second stage:

    install: cannot create directory '/var': No space left on device

A previous version of `make-ext4-fs' (before PR NixOS#79368) was explicitly
"reserving" 16 MiB of free space in the final filesystem.  Manually
calculating the size of an ext4 filesystem is a perilous endeavor,
however, and the method it employed was apparently unreliable.

Reverting is consequently not a good option.

A solution would be to create some sort of "balloon" occupying inodes
and blocks in the image prior to invoking `resize2fs -M', and to remove
these temporary files/directories before the compression step.

This changeset takes the simpler approach of simply dropping the
resizing step.

Note that this does *not* result in a larger image in general, as the
current procedure does not truncate the `.img' file anyway.  In fact, it
has been observed to yield *smaller* compressed images---probably
because of some "noise" left after resizing.  E.g., before-vs-after:

    -r--r--r-- 2 root root 607M  1. Jan 1970  nixos-sd-image-21.11pre-git-x86_64-linux.img.zst

    -r--r--r-- 2 root root 606M  1. Jan 1970  nixos-sd-image-21.11pre-git-x86_64-linux.img.zst
github-actions bot pushed a commit that referenced this pull request Jun 1, 2021
The root filesystem resizing step, `resize2fs -M', does not provide any
control over the amount of slack left in the result.  It can produce an
arbitrarily tight fit, depending on how well the payload aligns with
ext4 data structures.

This is problematic, as NixOS must create a few files and directories
during its first boot, before the root is enlarged to match the size of
the containing SD card.

An overly tight fit can cause failures in the first stage:

    mkdir: can't create directory '/mnt-root/proc': No space left on device

or in the second stage:

    install: cannot create directory '/var': No space left on device

A previous version of `make-ext4-fs' (before PR #79368) was explicitly
"reserving" 16 MiB of free space in the final filesystem.  Manually
calculating the size of an ext4 filesystem is a perilous endeavor,
however, and the method it employed was apparently unreliable.

Reverting is consequently not a good option.

A solution would be to create some sort of "balloon" occupying inodes
and blocks in the image prior to invoking `resize2fs -M', and to remove
these temporary files/directories before the compression step.

This changeset takes the simpler approach of simply dropping the
resizing step.

Note that this does *not* result in a larger image in general, as the
current procedure does not truncate the `.img' file anyway.  In fact, it
has been observed to yield *smaller* compressed images---probably
because of some "noise" left after resizing.  E.g., before-vs-after:

    -r--r--r-- 2 root root 607M  1. Jan 1970  nixos-sd-image-21.11pre-git-x86_64-linux.img.zst

    -r--r--r-- 2 root root 606M  1. Jan 1970  nixos-sd-image-21.11pre-git-x86_64-linux.img.zst

(cherry picked from commit 7c2adb1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants