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/initrd: Add thin-provisioning-tools binaries #46541

Closed
wants to merge 1 commit into from

Conversation

YorikSar
Copy link
Contributor

Motivation for this change

This enables usage of thin and cache volumes without ugly hacks (see #15516). With my conifiguration on 18.03, size of initrd before this change is 12470611 and after is 13542353, only 8.6% increase.

These files are added to extra-utils:

lrwxrwxrwx      11 result/bin/cache_check -> pdata_tools
lrwxrwxrwx      11 result/bin/cache_dump -> pdata_tools
lrwxrwxrwx      11 result/bin/cache_metadata_size -> pdata_tools
lrwxrwxrwx      11 result/bin/cache_repair -> pdata_tools
lrwxrwxrwx      11 result/bin/cache_restore -> pdata_tools
lrwxrwxrwx      11 result/bin/era_check -> pdata_tools
lrwxrwxrwx      11 result/bin/era_dump -> pdata_tools
lrwxrwxrwx      11 result/bin/era_invalidate -> pdata_tools
lrwxrwxrwx      11 result/bin/era_restore -> pdata_tools
-r-xr-xr-x 1350576 result/bin/pdata_tools
lrwxrwxrwx      11 result/bin/thin_check -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_delta -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_dump -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_ls -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_metadata_size -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_repair -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_restore -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_rmap -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_trim -> pdata_tools
-r-xr-xr-x    7016 result/lib/libaio.so.1
-r-xr-xr-x  221072 result/lib/libexpat.so.1
-r--r--r--  100608 result/lib/libgcc_s.so.1
-r-xr-xr-x 1558864 result/lib/libstdc++.so.6

Fixes #15516

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option 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/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Fits CONTRIBUTING.md.

This enables usage of thin and cache volumes without ugly hacks
(see NixOS#15516). With my conifiguration on 18.03, size of initrd before
this change is 12470611 and after is 13542353, only 8.6% increase.
These files are added to extra-utils:

lrwxrwxrwx      11 result/bin/cache_check -> pdata_tools
lrwxrwxrwx      11 result/bin/cache_dump -> pdata_tools
lrwxrwxrwx      11 result/bin/cache_metadata_size -> pdata_tools
lrwxrwxrwx      11 result/bin/cache_repair -> pdata_tools
lrwxrwxrwx      11 result/bin/cache_restore -> pdata_tools
lrwxrwxrwx      11 result/bin/era_check -> pdata_tools
lrwxrwxrwx      11 result/bin/era_dump -> pdata_tools
lrwxrwxrwx      11 result/bin/era_invalidate -> pdata_tools
lrwxrwxrwx      11 result/bin/era_restore -> pdata_tools
-r-xr-xr-x 1350576 result/bin/pdata_tools
lrwxrwxrwx      11 result/bin/thin_check -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_delta -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_dump -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_ls -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_metadata_size -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_repair -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_restore -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_rmap -> pdata_tools
lrwxrwxrwx      11 result/bin/thin_trim -> pdata_tools
-r-xr-xr-x    7016 result/lib/libaio.so.1
-r-xr-xr-x  221072 result/lib/libexpat.so.1
-r--r--r--  100608 result/lib/libgcc_s.so.1
-r-xr-xr-x 1558864 result/lib/libstdc++.so.6

Fixes NixOS#15516
@xeji
Copy link
Contributor

xeji commented Sep 11, 2018

I run a system with thin lvm. To boot my system, initrd doesn't need all of these tools, only thin-check (which I currently add using preLVMCommands). I'm not sure the others are really necessary to boot.

Also I think adding thin lvm tools should be made conditional on actually using thin lvm instead of adding them "just in case".

IMO the best solution is a new NixOS options boot.initrd.useThinLVM (or whatever better name) that activates the kernel module and adds the necessary tool(s) to initrd.

@YorikSar
Copy link
Contributor Author

@xeji I just managed to bring my system back up after migration to thin volumes using this hack:

  boot.initrd.extraUtilsCommands = ''
    copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/pdata_tools
    copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/thin_check
  '';
  boot.initrd.preLVMCommands = ''
    mkdir -p /etc/lvm
    echo "global/thin_check_executable = \"$(which thin_check)\"" >> /etc/lvm/lvm.conf
  '';

just adding thin_check symlink and pdata_tools binary doesn't cut it.

All other binaries are just symlinks to pdata_tools like thin_check is, so they add nothing to the size of initrd, but allow to support cached volumes as well as repairing all of them, so I think we should keep them around.

As for adding another option, I though about that, but after I found out that size of initrd doesn't change much, decided to push it without option first. I guess I'll add smth like enableLVMThinCache, to highlight support for both cache and thin volumes. Another option would be to add a list of features like boot.initrd.enableLVMFeatures = [ "thin" "cache" ] that would also add appropriate kernel modules to initrd as well. In that case we could default it to smth like [ "basic" ] and allow user to specify empty list to avoid adding LVM stuff altogether if it's not needed.

What do you think?

@xeji
Copy link
Contributor

xeji commented Sep 11, 2018

All other binaries are just symlinks to pdata_tools like thin_check is, so they add nothing to the size of initrd,

Right, I didn't realize that, so adding them all is fine.

I like the idea to have one option to activate both the kernel module and necessary tools. My personal preference would be to have simple boolean options, sth like: boot.initrd.lvmThin.enable and boot.initrd.lvmCache.enable rather than a feature list (but that's not a strong opinion).

Let's wait a little and see what other people think about the 1MB increase in initrd size first.

@Mic92
Copy link
Member

Mic92 commented Sep 12, 2018

This makes me wonder why stuff like mdadm is included by default.

@xeji
Copy link
Contributor

xeji commented Sep 12, 2018

Yep, mdadm could also be optional. (1MB), although making it optional will break some existing configs...

@YorikSar
Copy link
Contributor Author

I think we should make initrd fully configurable, defaulting to current state. This way if one cares one can strip it down to only what is needed for one's config. We'll have to carve things out of stage1 as well though.

@Mic92
Copy link
Member

Mic92 commented Sep 13, 2018

mdadm could be also not included based on the stateVersion to avoid breakages of configuration.

@xeji
Copy link
Contributor

xeji commented Sep 13, 2018

We could do that, and I would, but there are strong objections to such uses of stateVersion, see e.g. #39329 (comment) .

@Mic92
Copy link
Member

Mic92 commented Sep 13, 2018

I only see limited values in making it optional but disabled by default. Most people will keep it then also they do not ever need it. Is it not possible to detect if mdadm or lvm are actually needed?

@YorikSar
Copy link
Contributor Author

It is possible to add such detection functionality to nixos-generate-config, for example, and explicitly disable everything not needed in hardware-configuration.nix. I'm not sure this would help existing users though, but for new installs this would bring smaller initrd.

@mmahut
Copy link
Member

mmahut commented Aug 9, 2019

Any updates on this pull request, please?

@ajs124 ajs124 mentioned this pull request May 23, 2020
10 tasks
@stale
Copy link

stale bot commented Jun 1, 2020

Thank you for your contributions.
This has been automatically marked as stale because it has had no activity for 180 days.
If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.
Here are suggestions that might help resolve this more quickly:

  1. Search for maintainers and people that previously touched the
    related code and @ mention them in a comment.
  2. Ask on the NixOS Discourse. 3. Ask on the #nixos channel on
    irc.freenode.net.

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 1, 2020
@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Oct 3, 2020
@SnVIZQ
Copy link
Contributor

SnVIZQ commented Oct 18, 2020

I have tried the release-2020.09, nixpkgs.git hash c6fa7bb today.

The boot works, though I see following (transcribed from screen shot so end lines are cut off):

Verifying passphrase for /dev/disk/by-uuid/... - success
Starting device mapper and LVM...
    /nix/store/eee...eee-thin-provisioning-tools-0.9.0/bin/cache_check: execvp fail...
    WARNING: Check is skipped, please install recommended missing binary /nix/store/eee...eee-thin-provisioning-tools-0.9.0/bin/cache_check!
    4 logical volume(s) in volume group "vg" now active
...

The cache check is skipped but it doesn't seem to be critical for the boot to progress.

@ajs124
Copy link
Member

ajs124 commented Oct 18, 2020

@SnVIZQ do you have services.lvm.boot.thin.enable (from here) set in your system configuration?

@SnVIZQ
Copy link
Contributor

SnVIZQ commented Oct 19, 2020

@ajs124, I didn't have it there, so I've added it. No difference though. Rechecked it is enabled:

$ nixos-option services.lvm.boot.thin.enable
Value:
true

Default:
false

Type:
"boolean"

Example:
true

Description:
"Whether to enable support for booting from ThinLVs."

Declared by:
[ "/var/nixos/nixpkgs/nixos/modules/tasks/lvm.nix" ]

Defined by:
[ "/etc/nixos/configuration.nix" ]

I've also replaced thin_check with cache_check:

$ git diff
diff --git a/nixos/modules/tasks/lvm.nix b/nixos/modules/tasks/lvm.nix
index 2c3cc4c5467..db0076bdfda 100644
--- a/nixos/modules/tasks/lvm.nix
+++ b/nixos/modules/tasks/lvm.nix
@@ -43,12 +43,12 @@ in {

         extraUtilsCommands = ''
           copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/pdata_tools
-          copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/thin_check
+          copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/cache_check
         '';
       };

       environment.etc."lvm/lvm.conf".text = ''
-        global/thin_check_executable = "${pkgs.thin-provisioning-tools}/bin/thin_check"
+        global/thin_check_executable = "${pkgs.thin-provisioning-tools}/bin/cache_check"
       '';
     })
     (mkIf (cfg.dmeventd.enable || cfg.boot.thin.enable) {
@@ -56,7 +56,7 @@ in {
           mkdir -p /etc/lvm
           cat << EOF >> /etc/lvm/lvm.conf
           ${optionalString cfg.boot.thin.enable ''
-            global/thin_check_executable = "$(command -v thin_check)"
+            global/thin_check_executable = "$(command -v cache_check)"
           ''}
           ${optionalString cfg.dmeventd.enable ''
             dmeventd/executable = "$(command -v false)"

... to see if would help, but nope... Still the same:

/nix/store/eee...eee-thin-provisioning-tools-0.9.0/bin/cache_check: execvp failed: No such file or directory

This looks to me like some lvm binary, which is trying to execute cache_check, is not properly adjusted. The old hack which replaces strings within binaries using perl voodoo:

  boot.initrd.extraUtilsCommands = ''
    # Put thin-provisioning-tools into extra-utils and patch lvm accordingly.
    # NOTE: this works only because thin-provisioning-tools string, including
    # version, is longer than extra-utils string. The difference is zeroed. If
    # it would be vice versa there is a chance it would not work because the
    # stuff after the full path to the tool would be overwritten. Although there
    # seem to be some other, documentation, string just behind the full path
    # name which might not be that important... Anyways, not spending time
    # to figure out how to avoid the patching in case it is not possible doing
    # the proper way.
    for BIN in ${pkgs.thin-provisioning-tools}/bin/*; do
      copy_bin_and_libs $BIN
      SRC="(?<all>/[a-zA-Z0-9/]+/[0-9a-z]{32}-[0-9a-z-.]+(?<exe>/bin/$(basename $BIN)))"
      REP="\"$out\" . \$+{exe} . \"\\x0\" x (length(\$+{all}) - length(\"$out\" . \$+{exe}))"
      PRP="s,$SRC,$REP,ge"
      ${pkgs.perl}/bin/perl -p -i -e "$PRP" $out/bin/lvm
    done
  '';
  boot.initrd.extraUtilsCommandsTest = ''
    # The thin-provisioning-tools use pdata_tools binary as a link target of
    # supported utils so it is enough to check only one, the others should
    # "just" work...
    $out/bin/pdata_tools cache_check -V
  '';

works fine though.

@stale
Copy link

stale bot commented Apr 18, 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 Apr 18, 2021
arianvp added a commit to arianvp/nixpkgs that referenced this pull request May 1, 2021
thin-provisioning-tools has a _huge_ closure size (hundreds of
megabytes) and the only reference in the output of the lvm2 package is a
_comment_ in the etc/lvm.conf

The lvm2 package thus does not seem to depend on thin-provisoning-tools
in any way.

Reverts 9326a89

thin provisoning is broken with or without this change:
NixOS#15516

A proper fix is here:
NixOS#46541

References:

$ nix why-depends nixpkgs#lvm2 nixpkgs#thin-provisioning-tools
/nix/store/n7zwwxi0ihjks7qk9bq5lbkniligfcqc-lvm2-2.03.11
└───etc/lvm.conf: …_check_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-prov>
    → /nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0

$ ag thin-provisioning-tools --search-binary
etc/lvm.conf
1093:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1095:	# thin_check_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/thin_check"
1100:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1102:	# thin_dump_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/thin_dump"
1108:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1110:	# thin_repair_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/thin_repair"
1155:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1157:	# cache_check_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/cache_check"
1162:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1164:	# cache_dump_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/cache_dump"
1170:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1172:	# cache_repair_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/cache_repair"
FRidh pushed a commit that referenced this pull request Jul 29, 2021
thin-provisioning-tools has a _huge_ closure size (hundreds of
megabytes) and the only reference in the output of the lvm2 package is a
_comment_ in the etc/lvm.conf

The lvm2 package thus does not seem to depend on thin-provisoning-tools
in any way.

Reverts 9326a89

thin provisoning is broken with or without this change:
#15516

A proper fix is here:
#46541

References:

$ nix why-depends nixpkgs#lvm2 nixpkgs#thin-provisioning-tools
/nix/store/n7zwwxi0ihjks7qk9bq5lbkniligfcqc-lvm2-2.03.11
└───etc/lvm.conf: …_check_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-prov>
    → /nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0

$ ag thin-provisioning-tools --search-binary
etc/lvm.conf
1093:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1095:	# thin_check_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/thin_check"
1100:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1102:	# thin_dump_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/thin_dump"
1108:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1110:	# thin_repair_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/thin_repair"
1155:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1157:	# cache_check_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/cache_check"
1162:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1164:	# cache_dump_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/cache_dump"
1170:	# (See package device-mapper-persistent-data or thin-provisioning-tools)
1172:	# cache_repair_executable = "/nix/store/w5an38q6byfr1sihks66srbqdii9hnsd-thin-provisioning-tools-0.9.0/bin/cache_repair"
@flokli
Copy link
Contributor

flokli commented Aug 4, 2021

@ajs124 could you take a look at this?

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Aug 4, 2021
@ajs124
Copy link
Member

ajs124 commented Aug 4, 2021

@SnVIZQ do you also have dm-cache mappings?

@SnVIZQ
Copy link
Contributor

SnVIZQ commented Aug 4, 2021

@SnVIZQ do you also have dm-cache mappings?

@ajs124 I'm not sure what exactly you mean by "dm-cache mappings", but my gut feeling is the answer is yes. The basic topology si like this: There's LUKS on low level - on SSDs and HDDs, on top of that is LVM, where HDDs use cache residing on SSD - the standard lvmcache(7) approach.

@ajs124
Copy link
Member

ajs124 commented Aug 4, 2021

That's what I meant, yes. LVM2 manages device mapper things for you. We currently only support booting from thin pools or lvmthin(7), but not lvmcache(7).

Can you try if this works:

diff --git a/nixos/modules/tasks/lvm.nix b/nixos/modules/tasks/lvm.nix
index 98a0e2ddef9..a4311c6baa9 100644
--- a/nixos/modules/tasks/lvm.nix
+++ b/nixos/modules/tasks/lvm.nix
@@ -48,11 +48,13 @@ in {
         extraUtilsCommands = ''
           copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/pdata_tools
           copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/thin_check
+          copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/cache_check
         '';
       };
 
       environment.etc."lvm/lvm.conf".text = ''
         global/thin_check_executable = "${pkgs.thin-provisioning-tools}/bin/thin_check"
+        global/cache_check_executable = "${pkgs.thin-provisioning-tools}/bin/cache_check"
       '';
     })
     (mkIf (cfg.dmeventd.enable || cfg.boot.thin.enable) {
@@ -61,6 +63,7 @@ in {
           cat << EOF >> /etc/lvm/lvm.conf
           ${optionalString cfg.boot.thin.enable ''
             global/thin_check_executable = "$(command -v thin_check)"
+            global/cache_check_executable = "$(command -v cache_check)"
           ''}
           ${optionalString cfg.dmeventd.enable ''
             dmeventd/executable = "$(command -v false)"

@SnVIZQ
Copy link
Contributor

SnVIZQ commented Aug 4, 2021

I have applied your patch (addition of cache_check stuff to lvm.nix) on top of b1ee3bc commit (release-21.05 branch from 2021-08-04_10-54-24), removed the "old hack" (extension of extraUtilsCommands{,Test} from my older post above), set the services.lvm.boot.thin.enable to true, rebuilt and activated this configuration and I can confirm it booted just fine.

So I'd vote for having the patch applied because it solves my issue. :-)

@ajs124
Copy link
Member

ajs124 commented Aug 5, 2021

We could do that, although the option kind of has a misleading name, then.

Then again, cache_check is just a symlink to pdata_tools, like thin_check, so this won't increase the initrd size. And the cache_* tools are part of thin-provisioning-tools.

I'll open a PR.

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.

NixOS: Handle lvm cached volumes properly
9 participants