Skip to content

Commit

Permalink
Merge overlayfs fix, LTS kernel bump and test
Browse files Browse the repository at this point in the history
In Linux 4.19 there has been a major rework of the overlayfs
implementation and it now opens files in lowerdir with O_NOATIME, which
in turn caused issues in our VM tests because the process owner of QEMU
doesn't match the file owner of the lowerdir.

The crux here is that 9p propagates the O_NOATIME flag to the host and
the guest kernel has no way of verifying whether that flag will lead to
any problems beforehand.

There is ongoing work to possibly fix this in the kernel, but it will
take a while until there is a working patch and consensus.

So in order to bring our default kernel back to 4.19 and of course make
it possible to run newer kernels in VM tests, I'm merging a small QEMU
patch as an interim solution, which we can drop once we have a working
fix in the next round of stable kernels.

Now we already had Linux 4.19 set as the default kernel, but that was
subsequently reverted in 048c36c
because the patch we have used was the revert of the commit I bisected a
while ago.

This patch broke overlayfs in other ways, so I'm also merging in a VM
test by @bachp, which only tests whether overlayfs is working, just to
be on the safe side that something like this won't happen in the future.

Even though this change could be considered a moderate mass-rebuild at
least for GNU/Linux, I'm merging this to master, mainly to give us some
time to get it into the current 19.03 release branch (and subsequent
testing window) once we got no new breaking builds from Hydra.

Cc: @samueldr, @lheckemann

Fixes: #54509
Fixes: #48828
Merges: #57641
Merges: #54508
  • Loading branch information
aszlig committed Mar 18, 2019
3 parents 8fce8a9 + 9a395a4 + a8307b9 commit 12efcc2
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 1 deletion.
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Expand Up @@ -174,6 +174,7 @@ in
osquery = handleTest ./osquery.nix {};
osrm-backend = handleTest ./osrm-backend.nix {};
ostree = handleTest ./ostree.nix {};
overlayfs = handleTest ./overlayfs.nix {};
pam-oath-login = handleTest ./pam-oath-login.nix {};
pam-u2f = handleTest ./pam-u2f.nix {};
pantheon = handleTest ./pantheon.nix {};
Expand Down
57 changes: 57 additions & 0 deletions nixos/tests/overlayfs.nix
@@ -0,0 +1,57 @@
import ./make-test.nix ({ pkgs, ... }: {
name = "overlayfs";
meta.maintainers = with pkgs.stdenv.lib.maintainers; [ bachp ];

machine = { pkgs, ... }: {
virtualisation.emptyDiskImages = [ 512 ];
networking.hostId = "deadbeef";
environment.systemPackages = with pkgs; [ parted ];
};

testScript = ''
$machine->succeed("ls /dev");
$machine->succeed("mkdir -p /tmp/mnt");
# Test ext4 + overlayfs
$machine->succeed(
"mkfs.ext4 -F -L overlay-ext4 /dev/vdb",
"mount -t ext4 /dev/vdb /tmp/mnt",
"mkdir -p /tmp/mnt/upper /tmp/mnt/lower /tmp/mnt/work /tmp/mnt/merged",
# Setup some existing files
"echo 'Replace' > /tmp/mnt/lower/replace.txt",
"echo 'Append' > /tmp/mnt/lower/append.txt",
"echo 'Overwrite' > /tmp/mnt/lower/overwrite.txt",
"mount -t overlay overlay -o lowerdir=/tmp/mnt/lower,upperdir=/tmp/mnt/upper,workdir=/tmp/mnt/work /tmp/mnt/merged",
# Test new
"echo 'New' > /tmp/mnt/merged/new.txt",
"[[ \"\$(cat /tmp/mnt/merged/new.txt)\" == \"New\" ]]",
# Test replace
"[[ \"\$(cat /tmp/mnt/merged/replace.txt)\" == \"Replace\" ]]",
"echo 'Replaced' > /tmp/mnt/merged/replace-tmp.txt",
"mv /tmp/mnt/merged/replace-tmp.txt /tmp/mnt/merged/replace.txt",
"[[ \"\$(cat /tmp/mnt/merged/replace.txt)\" == \"Replaced\" ]]",
# Overwrite
"[[ \"\$(cat /tmp/mnt/merged/overwrite.txt)\" == \"Overwrite\" ]]",
"echo 'Overwritten' > /tmp/mnt/merged/overwrite.txt",
"[[ \"\$(cat /tmp/mnt/merged/overwrite.txt)\" == \"Overwritten\" ]]",
# Test append
"[[ \"\$(cat /tmp/mnt/merged/append.txt)\" == \"Append\" ]]",
"echo 'ed' >> /tmp/mnt/merged/append.txt",
#"cat /tmp/mnt/merged/append.txt && exit 1",
"[[ \"\$(cat /tmp/mnt/merged/append.txt)\" == \"Append\ned\" ]]",
"umount /tmp/mnt/merged",
"umount /tmp/mnt",
"udevadm settle"
);
'';
})
44 changes: 44 additions & 0 deletions pkgs/applications/virtualization/qemu/9p-ignore-noatime.patch
@@ -0,0 +1,44 @@
commit cdc3e7eeafa9f683214d2c15d52ef384c3de6611
Author: aszlig <aszlig@nix.build>
Date: Mon Mar 18 13:21:01 2019 +0100

9pfs: Ignore O_NOATIME open flag

Since Linux 4.19, overlayfs uses the O_NOATIME flag on its lowerdir,
which in turn causes errors when the Nix store is mounted in the guest
because the file owner of the store paths typically don't match the
owner of the QEMU process.

After submitting a patch to the overlayfs mailing list[1], it turns out
that my patch was incomplete[2] and needs a bit more rework.

So instead of using an incomplete kernel patch in nixpkgs, which affects
*all* users of overlayfs, not just NixOS VM tests, I decided that for
now it's better to patch QEMU instead.

The change here really only ignores the O_NOATIME flag so that the
behaviour is similar to what NFS does. From open(2):

This flag may not be effective on all filesystems. One example is NFS,
where the server maintains the access time.

This change is therefore only temporary until the final fix lands in the
stable kernel releases.

[1]: https://www.spinics.net/lists/linux-unionfs/msg06755.html
[2]: https://www.spinics.net/lists/linux-unionfs/msg06756.html

Signed-off-by: aszlig <aszlig@nix.build>

diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 55821343e5..0b8425fe18 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -127,7 +127,6 @@ static int dotl_to_open_flags(int flags)
{ P9_DOTL_LARGEFILE, O_LARGEFILE },
{ P9_DOTL_DIRECTORY, O_DIRECTORY },
{ P9_DOTL_NOFOLLOW, O_NOFOLLOW },
- { P9_DOTL_NOATIME, O_NOATIME },
{ P9_DOTL_SYNC, O_SYNC },
};

1 change: 1 addition & 0 deletions pkgs/applications/virtualization/qemu/default.nix
Expand Up @@ -76,6 +76,7 @@ stdenv.mkDerivation rec {
patches = [
./no-etc-install.patch
./fix-qemu-ga.patch
./9p-ignore-noatime.patch
] ++ optional nixosTestRunner ./force-uid0-on-9p.patch
++ optional pulseSupport ./fix-hda-recording.patch
++ optionals stdenv.hostPlatform.isMusl [
Expand Down
2 changes: 1 addition & 1 deletion pkgs/top-level/all-packages.nix
Expand Up @@ -14903,7 +14903,7 @@ in
});

# The current default kernel / kernel modules.
linuxPackages = linuxPackages_4_14;
linuxPackages = linuxPackages_4_19;
linux = linuxPackages.kernel;

# Update this when adding the newest kernel major version!
Expand Down

0 comments on commit 12efcc2

Please sign in to comment.