In container: `chown: [...] Value too large for defined data type`

Hi! I’m trying to implement mountOptions for bindMounts in nixos Containers described in this issue to do a PR later.

I’ve implemented it so far and everything seems ok from the nix side, but when trying to test it, I’m getting an error which I don’t know how to handle.

The test case

I’m trying to recreate the test case in this commit, but with nixos on my nixpkgs fork. Everything works ok, but the ownership within the container doesn’t change from root:root.

When I’m logging into the container to change the ownership manually (via # chown -R testUser:testUser /home/testUser), I get this error message:

chown: changing ownership of '/home/testUser/file': Value too large for defined data type
chown: changing ownership of '/home/testUser/lost+found': Value too large for defined data type
chown: changing ownership of '/home/testUser/': Value too large for defined data type

I have no idea why it does this. It seems like some low-level stuff, possibly connected to 64/32bit stuff. But I’m running on a 64bit machine. Am I missing something?

Here’s the testService I’ve used to set it up:

{pkgs, ...}:
let
  rootPath = "/tmp/owneridmap";
  containerPath = "/home/testUser";
in {
  systemd.services.testHostService = {
    enable = true;
    wantedBy = ["multi-user.target"];

    description = "Create a new file";
    serviceConfig = {
      Type = "oneshot";
    };
    script = ''
      mkdir -p ${rootPath}/bind
      ${pkgs.coreutils}/bin/dd if=/dev/zero of=${rootPath}/ext4.img bs=4k count=2048

      ${pkgs.e2fsprogs}/bin/mkfs.ext4 ${rootPath}/ext4.img
      ${pkgs.util-linux.mount}/bin/mount ${rootPath}/ext4.img ${rootPath}/bind
      
      touch ${rootPath}/bind/file

      chown -R hostUser:hostUser ${rootPath}/bind
    '';
    requiredBy = [
      "container@testContainer.service"
    ];
  };

  containers.testContainer = {
    autoStart = true;
    ephemeral = true;

    bindMounts = {
      "${containerPath}" = {
        hostPath = "${rootPath}/bind";
        isReadOnly = false;
        mountOptions = "owneridmap";
      };
    };

    config = {pkgs, ...}:{
      users.users.testUser = {
        uid = 1010;
        isNormalUser = true;
      };
      users.users.testUser.group = "testUser";
      users.groups.testUser = {};

      systemd.tmpfiles.rules = [ "d ${containerPath} 777 testUser testUser" ];

      systemd.services.testContainerService = {
        enable = true;
        wantedBy = ["multi-user.target"];

        description = "Create a new file in the container";
        serviceConfig = {
          Type = "oneshot";
        };
        script = ''
          # Neither this, nor `systemd.tmpfiles.rules` works
          chown -R testUser:testUser ${containerPath}

          ${pkgs.sudo}/bin/sudo -u testUser touch ${containerPath}/another_file
        '';
      };
    };
  };
}

Edit – Additional finding --:

According to this comment, these errors unually occur if the GNU utilities were not compiled with large file support enabled. I don’t really get it, since the documentation that comment points to talks about big files > 2GB and chmod fails on a directory with three empty files. Also: If this was the problem, this would affect the build flags of systemd… which is a teeny bit above my level for the first contribution to the nix ecosystem. xD

Ok, apparently 4*2048kb is simply too small for the test partition. It works with e.g. 200MB. Stupid mistake on my side.

Unfortunately, Mountbinding still doesn’t work. But that’s a different topic. :frowning:

Just hit the same issue in container (with "--private-users=pick") on nixos-24.11 (not a virtual machine):
with owneridmap it looks like the owner of the mountPoint cannot be changed once the bind mount is done by nspawn.
If mountPoint already exists and is owned by the user you want before spawning the container, then owneridmap works as expected…
But this make owneridmap mostly impractical and fragile, as you would usually have to restart the container once to make the mount work correctly. So back to idmap for me.