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

[wip] kernel: attempt to rerun unpackPhase if sthg fishy (e.g. buildRoot unset) #31463

Closed
wants to merge 17 commits into from

Conversation

teto
Copy link
Member

@teto teto commented Nov 10, 2017

When trying to compile/hack the kernel, nixos would keep asking me to
generate the .config file. That was because I had skipped the
unpackPhase.
Also if one exits the nix-shell (voluntarely or because of an error) and wants to resume the configure phase, it fails too because '$buildRoot' is not set; it is set during the unpackPhase.

My tackle on that is that there is a great chance the nix-shell was resumed from the unpacked folder.
Then the configurePhase sets the buildRoot accordingly, assuming we are in the unpacked folder.

I could have done it via a preConfigure hook but either way the current
situation is not good since one doesn"t know why he is asked to generate
the config. Dying with a message "set $buildRoot" could be an option.

Motivation for this change
Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option build-use-sandbox in nix.conf on non-NixOS)
  • 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 nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Fits CONTRIBUTING.md.

@orivej
Copy link
Contributor

orivej commented Nov 10, 2017

I'd just move this from preUnpack into configurePhase:

        mkdir -p ../build
        export buildRoot="$(pwd)/../build"

@teto
Copy link
Member Author

teto commented Nov 13, 2017

I tried on a nix build but I don't think it works. buildRoot seems to be useful mostly to grab the config but I don't fully grasp where/when the config is generated, only related link #14721. Isn't it possible to defer the config generation or reregenerate it if it can't be found ? that would solve my problem and kinda makes sense. I would expect the kernel configurePhase to generate it (while it does nothing now)

$ls -la ~/mptcp2/build
-rw-r--r--  1 teto users 187139 11-14 04:04 .config
lrwxrwxrwx  1 teto users     75 11-14 04:04 .config.old -> /nix/store/wbsb0m2m3s091m59bgnhkvsbczz1czg1-linux-config-4.9.60-mptcp_v0.93
applying patch /nix/store/h4c3bag6lv3y47sbx83339xnalmlmdmg-modinst-arg-list-too-long.patch
patching file scripts/Makefile.modinst
configuring
'/home/teto/mptcp2/build/.config' -> '/nix/store/wbsb0m2m3s091m59bgnhkvsbczz1czg1-linux-config-4.9.60-mptcp_v0.93'
make[1] : on entre dans le répertoire « /home/teto/mptcp2/build »
  HOSTCC  scripts/basic/fixdep
  GEN     ./Makefile
  HOSTCC  scripts/kconfig/conf.o
  SHIPPED scripts/kconfig/zconf.tab.c
  SHIPPED scripts/kconfig/zconf.lex.c
  SHIPPED scripts/kconfig/zconf.hash.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf  --oldconfig Kconfig
#
# configuration written to .config
#
make[1] : on quitte le répertoire « /home/teto/mptcp2/build »
make[1] : on entre dans le répertoire « /home/teto/mptcp2/build »
  GEN     ./Makefile

@teto
Copy link
Member Author

teto commented Nov 14, 2017

So Ive defined an overlay

  mptcp-local = super.pkgs.linux_mptcp.override ({
    # NIX_DEBUG=8;
    src= super.lib.cleanSource /home/teto/mptcp;
    modDirVersion="4.9.60+";
  });

and when I run
nix-shell -A mptcp-local ~/nixpkgs --show-trace
it starts doing stuff while I would expect it to do nothing (but installs kernel buildInputs such as bash)

warning: dumping very large path (> 256 MiB); this may run out of memory
these derivations will be built:
  /nix/store/pcvwpjxj8xyb0gfn2if000l28zb17xyi-linux-config-4.9.60-mptcp_v0.93.drv
building path(s) ‘/nix/store/4rc658fxvc140mb8qrwcjvkdv4xq51xx-linux-config-4.9.60-mptcp_v0.93’
unpacking sources
unpacking source archive /nix/store/529lr785fp8nyx2m2dq7rdyw2avw1a87-mptcp
source root is mptcp
patching sources
stripping FHS paths in `./tools/lguest/Makefile'...
stripping FHS paths in `./tools/build/Makefile.include'...
stripping FHS paths in `./tools/build/Makefile'...
stripping FHS paths in `./tools/build/feature/Makefile'...
stripping FHS paths in `./tools/build/tests/ex/Makefile'...

@teto
Copy link
Member Author

teto commented Nov 15, 2017

So I got some more understanding of the problem also thanks to clever, i.e., even if your src is local, it will be fetched to the store (which explains why nix-repl> mptcp-local.src prints a path to the store, which surprised me at first). The special bit compared to other software is that one derviation inherits the kernel source, aka the config derivation in generic.nix with
inherit (kernel) src patches preUnpack;
Thus any change I would make to the src would trigger a config regeneration (aka a copy of the file/patchingPhase/make config). So it's better to leave the upstream source because the config is generated only once and can be used after in the nix-shell.
(then I had wrong include path for seemingly no reason until I ran mrproper).

Now it compiles but I notice it compiles a lot of things. I intend to build a minimal image for qemu testing purpose. How can I prevent config generation and use my own, there seems to be the config

# Manually specified nixexpr representing the config
  # If unspecified, this will be autodetected from the .config
  config ? stdenv.lib.optionalAttrs allowImportFromDerivation (readConfig configfile),

Back to the initial issue, it might be best during the configPhase to not assume any specific folder and ask the user instead where he wants to build, sthg like

 if [ -z "$buildRoot" ]; then

          # assume we are in the $sourceRoot folder
          echo "buildRoot is not set, please set it to the folder where you want to build"
          exit
 else
  mkdir $buildRoot/build
...

Copy link
Member

@layus layus left a comment

Choose a reason for hiding this comment

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

Oops. My review was never submitted apparently...

@@ -103,7 +103,16 @@ let

configurePhase = ''
runHook preConfigure
if [ -z "$buildRoot" ]; then
Copy link
Member

Choose a reason for hiding this comment

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

This should go into the shellHook attribute. The shellHook is executed at the begining of every nix-shell invocation.

ln -sv ${configfile} $buildRoot/.config
# ln -sv ${configfile} ''${buildRoot:=$(pwd)/../build}/.config
Copy link
Member

Choose a reason for hiding this comment

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

This looks like something you do not want to commit ;-)

@teto teto changed the title kernel: attempt to rerun unpackPhase if sthg fishy (e.g. buildRoot unset) [wip] kernel: attempt to rerun unpackPhase if sthg fishy (e.g. buildRoot unset) Nov 21, 2017
@teto
Copy link
Member Author

teto commented Nov 21, 2017

I forgot this branch was a PR and started pushing some random stuff but I tried just the initial patch with nix-build it won't work. So I can't remove the preUnpack phase, at least not without doing some extra debugging

/nix/store/izkijl7w7qkjdfr09qk43v1n3bnbdnvm-stdenv/setup: line 1047: cd: /homeless-shelter: No such file or directory
builder for ‘/nix/store/1c96x4kxk266c7xgv0haqwa78n7rz04y-linux-config-4.9.60-mptcp_v0.93.drv’ failed with exit code 1
error: build of ‘/nix/store/1c96x4kxk266c7xgv0haqwa78n7rz04y-linux-config-4.9.60-mptcp_v0.93.drv’ failed

The patch

diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix
index 28ad5aeca35..bbc5b2dcf46 100644
--- a/pkgs/os-specific/linux/kernel/manual-config.nix
+++ b/pkgs/os-specific/linux/kernel/manual-config.nix
@@ -87,8 +87,8 @@ let
       inherit src;
 
       preUnpack = ''
-        mkdir build
-        export buildRoot="$(pwd)/build"
+        # mkdir build
+        # export buildRoot="$(pwd)/build"
       '';
 
       patches = map (p: p.patch) kernelPatches;
@@ -102,6 +102,13 @@ let
       '';
 
       configurePhase = ''
+        # if [ -z "$buildRoot" ]; then
+
+          # assume we are in the $sourceRoot folder
+          echo "buildRoot is not set"
+          mkdir build
+          export buildRoot="$PWD/build"
+        # fi
         runHook preConfigure
         ln -sv ${configfile} $buildRoot/.config
         make $makeFlags "''${makeFlagsArray[@]}" oldconfig

When trying to compile/hack the kernel, it would keep asking me to
generate the .config file. That was because I had skipped the
unpackPhase. Also if one exit the nix-shell (voluntarely or because of
	an error) and wants to resume the configure phase, it would fail
because '$buildRoot' is not set; it is set during the unpackPhase.

My tackle on that is that there is a great chance the nix-shell was resumed from the unpacked folder.
Then the configurePhase sets the buildRoot accordingly.
I could have done it via a preConfigure hook but either way the current
situation is not good since one doesn"t know why he is asked to generate
the config. Dying with a message "set $buildRoot" could be an option.
…ell etc wip in pkgs/os-specific/linux/kernel/config.nix
===========
En gros on a linux_mptcp = callPackage generic.nix (linux_mptcp.nix)
generic.nix fait appel a buildLinux qui est defini dans manual-config.nix
generic.nix importe aussi kernelPlatform: import ./common-config.nix

extraConfig (optional) is a string specifying extra options to be concatenated to the kernel configuration file (.config)
===========

kernelPatches is a set of
  bridge_stp_helper =
    { name = "bridge-stp-helper";
      patch = ./bridge-stp-helper.patch;
    };

'make oldconfig' It reads the existing .config file and prompts the user for options in the current kernel source that are not found in the file. This is useful when taking an existing configuration and moving it to a new kernel

configfile est un chemin vers le fichier au format '.config' tandis que 'config'
  pcBase = {
    name = "pc";
    kernelHeadersBaseConfig = "defconfig";
    kernelBaseConfig = "defconfig";
    # Build whatever possible as a module, if not stated in the extra config.
    kernelAutoModules = true;
    kernelTarget = "bzImage";
  };

  pc64 = pcBase // { kernelArch = "x86_64"; };

 kernelTargets

    kernelExtraConfig =
      ''
        # Ubi for the mtd
        MTD_UBI y
        UBIFS_FS y
        UBIFS_FS_XATTR y
        UBIFS_FS_ADVANCED_COMPR y
        UBIFS_FS_LZO y
        UBIFS_FS_ZLIB y
        UBIFS_FS_DEBUG n
      '';

dans la phase de build du noyau
make -C ../$sourceRoot O=$PWD $kernelBaseConfig ARCH=$arch

warning: dumping very large path (> 256 MiB); this may run out of memory

 Using .. as source for kernel
- merge config/kernel and have a stopAtConfig boolean ?
- override src of config ?
- have 2 different configs ? embedded/inplace
fixed perl script. this works in nix-shell but now fails with nix-build,
      aka nixops fails .
@teto
Copy link
Member Author

teto commented Jan 9, 2018

Closing this, there are so many ways kernel building could be improved, this deserves a more comprehensive approach.

@teto teto closed this Jan 9, 2018
@teto teto mentioned this pull request Jan 28, 2018
8 tasks
@teto teto deleted the kernel branch February 9, 2018 03:50
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

4 participants