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

modules-closure.sh: rewrite to use modinfo #107871

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

xaverdh
Copy link
Contributor

@xaverdh xaverdh commented Dec 29, 2020

Motivation for this change

Should fix #60416 (leakage of information from the building system), because modinfo only looks at the dependency information in the modules themselves.
Because modinfo only lists direct dependencies, we have to compute the closure ourselves with this approach.

Assumptions in the current implementation:

  • every kernel module has one and only one name (where name is what modinfo -F name produces)

There are two additional assumptions I did not make, but which could be used to simplify the code if they hold:

  • there are no cycles in the module dependency graph
  • modinfo -F depends produces unique names (which do not resolve to several modules)

This should produce bit-for-bit identical results compared to the old version (unless you have modules / module options on your kernel cmdline of course). You can (and should) check that with diffoscope.

Things done

So far I tested this on my local system.

  • 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.

@xaverdh
Copy link
Contributor Author

xaverdh commented Dec 29, 2020

@lheckemann do you think this is a sane approach generally? (not asking you to review the code just yet, bash can cause quite a headache)

@xaverdh
Copy link
Contributor Author

xaverdh commented Dec 29, 2020

Side remark: I would have much preferred to write this is a proper language (vs bash). It would be quite nice to settle on a language for nontrivial builders in nixpkgs..

@lheckemann
Copy link
Member

👍 on the idea.

Regarding a different language: I'm not sure a bash-free build would sell well since you lose stdenv, but I'm all for writing a different-language script to do the actual logic and using it from the bash builder (like for configuring the kernel, where the logic happens in perl).

there are no cycles in the module dependency graph

That should be a safe assumption: modules can't be loaded if their dependencies aren't loaded yet.

@xaverdh
Copy link
Contributor Author

xaverdh commented Dec 29, 2020

Regarding a different language: I'm not sure a bash-free build would sell well since you lose stdenv, but I'm all for writing a different-language script to do the actual logic and using it from the bash builder (like for configuring the kernel, where the logic happens in perl).

Actually an interpreted language is probably not a good idea here, since this code will run locally on almost every NixOS machine, so the interpreter would effectively slip into the runtime closure. I would be quite happy to write this external program in, say haskell, but I am not quite sure if people are willing to have ghc in the build time closure of (a minimal) NixOS (even if it doesn't need to run on every machine).

there are no cycles in the module dependency graph

That should be a safe assumption: modules can't be loaded if their dependencies aren't loaded yet.

Thats good to know! I noticed that it won't help as much as I initially thought though, because two modules still can depend on a common one, so the undirected graph may (and likely will) still have cycles. So we still need to either track seen modules, or accept that we visit nodes several times, which is bad performance wise.

@lheckemann
Copy link
Member

Actually an interpreted language is probably not a good idea here, since this code will run locally on almost every NixOS machine, so the interpreter would effectively slip into the runtime closure.

We already require perl in the runtime closure since a number of core nixos utilities (e.g. the /etc/passwd generator script) are written in perl, and python is in the closure of any system using grub (dependency via libzfs) or systemd-boot (boot menu generator script is written in python). That said, I'm not sure I understand how it would get into the runtime closure? After all, it's only used within the derivation, and the derivation's output (modules closure) certainly shouldn't have any references to the interpreter.

Hard agree on not pulling ghc in though. :)

which is bad performance wise.

I think this is premature optimisation, module closure generation (a) doesn't happen that often, and (b) is still going to be orders of magnitude faster than other steps that usually happen at the same time, e.g. evaluating the system config. Though I don't think tracking seen modules would be too hard?

@xaverdh
Copy link
Contributor Author

xaverdh commented Dec 29, 2020

That said, I'm not sure I understand how it would get into the runtime closure? After all, it's only used within the derivation, and the derivation's output (modules closure) certainly shouldn't have any references to the interpreter.

Well formally speaking its not in the runtime closure, but since most people build their initrd on the system itself, they will need the interpreter.

which is bad performance wise.

I think this is premature optimisation, module closure generation (a) doesn't happen that often, and (b) is still going to be orders of magnitude faster than other steps that usually happen at the same time, e.g. evaluating the system config. Though I don't think tracking seen modules would be too hard?

Its already implemented actually, I was thinking about dropping it to simplify the code.

@xaverdh
Copy link
Contributor Author

xaverdh commented Dec 29, 2020

Ok lets stick with the bash implementation for now.

@xaverdh xaverdh marked this pull request as ready for review December 29, 2020 18:41
@xaverdh
Copy link
Contributor Author

xaverdh commented Dec 29, 2020

cc @iblech (as an expert on bash scripting)

@iblech
Copy link
Contributor

iblech commented Jan 1, 2021

😊 That's very kind of you. Let's say that I went enough times through quoting hell that I now know my path through that hell. :-) Also I never worked with arrays in bash. In line 124, is there a particular reason why you don't use -n or -z? Generally, this seems like the safer path (though in this case it doesn't matter). On line 73, in the comment, you have a double "if".

Thank you for your work on #60416!

@xaverdh
Copy link
Contributor Author

xaverdh commented Jan 8, 2021

blush That's very kind of you. Let's say that I went enough times through quoting hell that I now know my path through that hell. :-) Also I never worked with arrays in bash. In line 124, is there a particular reason why you don't use -n or -z? Generally, this seems like the safer path (though in this case it doesn't matter). On line 73, in the comment, you have a double "if".

Thank you for your work on #60416!

The motivation for the +x pattern in line 124 is that it also works if the arrays elements are empty strings (i.e. it actually checks for the presence of the entry in the array).
The double ifis fixed, thanks!

@lheckemann
Copy link
Member

lheckemann commented Jan 12, 2021

@ofborg test boot zfs

and again

@xaverdh
Copy link
Contributor Author

xaverdh commented Jan 12, 2021

@ofborg test boot zfs

That might or might not work currently due to #78430, I will rebase this once #109030 is merged.

@xaverdh
Copy link
Contributor Author

xaverdh commented Jan 12, 2021

also I gave rust a shot in the pr linked above

@Mic92
Copy link
Member

Mic92 commented Jan 12, 2021

the other PR is merged now.

@stale
Copy link

stale bot commented Jul 12, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jul 12, 2021
@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Mar 20, 2024
@wegank wegank marked this pull request as draft March 25, 2024 16:12
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.

Kernel build is not sandboxed
5 participants