Closed tbaumann closed 1 month ago
Building without obviously works. But it would be better if it could just be made to work.
unshare: unshare failed: Invalid argument
Oh, that's a shame.
While it doesn't change the fact that unshare
will need to go away, I am curious about the following.
What distro you're on?
Does it have CONFIG_USER_NS
in /proc/config.gz
?
Does it have the following file and what is it set to cat /proc/sys/user/max_user_namespaces
? Apparently Debian and a few others have custom sysctl knobs that disable userns's to regular users as well.
Does unshare -U -- id -u
work at your shell?
Does unshare -U -r -- id -u
work at your shell?
Anything odd about your environment worth mentioning, such as nix running in a rootless container/a container/etc.
Now, on to how to fix this. There are a couple of options, but a revert is not on the table with this one sadly. Prior to the merge-commit 987002c, which began using mkfs.btrfs with subvol support and unshare
, the btrfs-subvol
image was subtly broken, and the plain btrfs
image was fully broken. ~I presume this is actually a regression, but I'm not sure when it came in, and it could be due to kernel, compiler, glibc, or mkfs.btrfs. I rolled back btrfs-progs to the same version of btrfs-progs in nixpkgs, and the issues remained, so it's not caused by btrfs-progs v6.11.~ ~Regression occurs between btrfs-progs v6.9.2 and v6.10.1.~ Bisected to https://github.com/kdave/btrfs-progs/commit/c6464d3f99ed1dabceff1168eabb207492c37624 between v6.10 and v6.10.1
The switch to unshare
was due to the fakeroot
command not working, and all the files created in the btrfs image were owned by UID 1000 and GID 100. This means all contents of /nix/store, /boot and the directories /, /nix, /nix/store, /boot were owned in this manner. The scripts that previously setup subvols on first-boot masked the worst of this, the ownership of /, which prevents sshd from starting as well as systemd-tmpfiles, which then breaks other services (dhcpcd, etc) as well due to missing directories. While going back to the RAMIFY scripts would allow it to build again, that opens up the system to being modified by UID 1000(First user), and some files GID 100 (users group by default), and that's a security problem, which is why revert is off the table.
Probably the simplest, on first-boot everything should be owned by root, so we could chown everything to root on first-boot. It would wreak havoc if it ever re-ran, and it would cause issues with user-pre-populated files.
Determine why fakeroot is failing (missing a function hook?) and fix it.
Figuire out where mkfs.btrfs gets its ownership from, and hard-code it to root.
For now, I'm taking option 3. I've got a patch that will simply make everything be owned by root.
What distro you're on? Does it have
CONFIG_USER_NS
in/proc/config.gz
?
shouldn't matter. It's all from stdenv
and nativeBuildInputs = [ ... util-linux ]
. Anyway, My os is Nixos current stable.
Does it have the following file and what is it set to
cat /proc/sys/user/max_user_namespaces
› cat /proc/sys/user/max_user_namespaces 191895
Does
unshare -U -- id -u
work at your shell? Doesunshare -U -r -- id -u
work at your shell?
~
› unshare -U -- id -u
65534
~
› unshare -U -r -- id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)
In my shell even the entire mkfs command works like in the source. Just not in the build env,
Anything odd about your environment worth mentioning, such as nix running in a rootless container/a container/etc.
Not that I can think of. All pretty standard. https://github.com/tbaumann/nix-conf/blob/main/nix/common/core.nix#L17
It's got to be a side effect for sure, because it must have worked for you. But I really don't see how. There isn't a debug mode. Maybe I should try strace to see where it fails.
Maybe fakeroot was broken the same way faketime was too. faketime -f "1970-01-01 00:00:01" ls -l
does not give all files fake [acm]time. But as far as I understood it should. only the date command is bent around correctly.
But I see no reason why LD_PRELOAD should be broken on Nix. So I'm probably just holding it wrong or have wrong expectations.
Maybe I can play around more tomorrow...
Does it have CONFIG_USER_NS in /proc/config.gz?
shouldn't matter. It's all from stdenv and nativeBuildInputs = [ ... util-linux ].
User namespaces are a kernel feature, so it's an impurity. But as you can use it as your user, then it's in your kernel.
I wonder if it is removed through syscall filtering done by the nix-daemon. Syscall filtering is big lists of allow/deny, and architecture does come into play with that, so that's possibly the cause of the difference.
Anyway, My os is Nixos current stable.
That's quite literally the best case scenario, no odd distro-patches coming into play here.
It's got to be a side effect for sure, because it must have worked for you.
Yea, it's odd, the environment I'm building in has very little customisation done to it, and has no virtualisation/containerisation configuration included. It's a orangepi5b, using this repo to configure it, with a nixpkgs kernel, plus impermanence and some network configuration.
This has got to be an x86_64-linux vs aarch64-linux impurity that is coming in from somewhere.
But I see no reason why LD_PRELOAD should be broken on Nix
Yea, in producing a quick hack to remove unshare
usage, I bisected btrfs-progs
, and stat is now no-longer happening in the btrfs binary, it happens when mkfs.btrfs calls a libc function, nftw
, which handles the stat and passes the stat struct back to mkfs.btrfs. That means libc is calling stat within itself, LD_PRELOAD doesn't work.
Anyways, I've created a workaround, removing unshare, and I've merged it to HEAD. e27fb7e96f3faf0e4b34dc34cc7eefde1e47b40d
Odd, I can run this on my x86_64 laptop.
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
};
outputs = {
self,
nixpkgs,
...
}: let
pkgs = nixpkgs.legacyPackages.x86_64-linux;
in {
packages.x86_64-linux = {
test = pkgs.stdenv.mkDerivation {
name = "unshare test";
nativeBuildInputs = [ pkgs.util-linux ];
buildCommand = ''
mkdir $out
id > $out/whoami.builduser
unshare -U -r id > $out/whoami.unshare
'';
};
};
};
}
grep '' result/*
result/whoami.builduser:uid=1000(nixbld) gid=100(nixbld) groups=100(nixbld)
result/whoami.unshare:uid=0(root) gid=0(root) groups=0(root)
I'm going to track the upstream bugs in #21
really odd
result/whoami.builduser:uid=1000(nixbld) gid=100(nixbld) groups=100(nixbld)
result/whoami.unshare:uid=0(root) gid=0(root) groups=0(root)
I don't see anything obviously wrong with the unshare arguments. It's probably specific to my system.