Skip to content

Docker build performance extremely slow due to lack of renameat2/overlayfs on ZFS #8648

Closed

Description

@dbavatar

System information

Type Version/Name
Distribution Name Any
Distribution Version Any
Linux Kernel Any
Architecture Any
ZFS Version Any
SPL Version Any

Describe the problem you're observing

This is more of a feature request than a bug. I can't find anyone actively tracking this problem, however I do know users of docker that have stopped using ZFS because of this after having stated there's something wrong with ZFS, which is unfortunate.

When using docker on a zfs dataset, the only option is docker's "zfs driver" which uses zfs dataset operations to create layered filesystems. On other filesystems such as ext4 and btrfs, the "overlay2 driver" (utilizing the kernel's overlayfs module) can be used which is extremely fast. Docker build times can go from a fraction of a second on ext4/overlay2 to several minutes on zfs/zfs.

overlay2 driver selection is currently blacklisted on zfs by docker:
https://github.com/moby/moby/blob/master/daemon/graphdriver/overlay2/overlay.go#L165

Note that btrfs added the necessary support in kernel 4.7:
https://github.com/moby/moby/blob/master/daemon/graphdriver/overlay2/overlay.go#L169

Describe how to reproduce the problem

From a performance perspective:
time the build of a Dockerfile with several layers as so:

time docker build . -t date_image
# date_image Dockerfile
FROM scratch
CMD [date]
CMD [date]
CMD [date]
CMD [date]
CMD [date]
# repeat date layer to magnify performance slowdown

From a functional perspective:

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <linux/fs.h>
#include <sys/syscall.h>

int main()
{
  int ret;

  ret = syscall(SYS_renameat2, 0, "/zfs/file1", 0, "/zfs/file2", RENAME_EXCHANGE);
  fprintf(stderr, "renameat2 ret=%d errno=%d\n", ret, errno);
  return ret;
}

Repeat test for RENAME_WHITEOUT flag as well.

I believe we should be able to use docker on ZFS w/overlay2 after both RENAME_EXCHANGE and RENAME_WHITEOUT are implemented in renameat2()

Activity

  1. cyphar commented on Apr 25, 2019

    @cyphar
    Contributor

    I've been working on this and renameat2(2) flag support is not sufficient to get overlayfs-on-ZFS working. The main blocker is that currently ZFS uses d_revalidate which means overlayfs refuses to use it as an upperdir. In order to fix it (in addition to #8667) we will need to rework a fair amount of the ported dcache-interacting code so that d_revalidate is no longer needed.

  2. added 8 commits that reference this issue on Oct 17, 2019
    1005377
    c413bc9
    3df5f60
    0863c25
    08955ab
    531ca2b
    0053613
    8fdd887
  3. added 6 commits that reference this issue on Nov 2, 2019
    c2b095c
    56d7501
    db12199
    c410b29
    2531793
    d47376b
  4. 40 remaining items

  5. Frederick888 commented on Jan 29, 2021

    @Frederick888

    I noticed that if I use ZFS as the lower layer of OverlayFS (upper, work, mount point in tmpfs), I cannot append contents to any existing files either.

    Sorry for my ignorance, but may I know if this problem is also tracked by this ticket or #9414? Thanks.

  6. cyphar commented on Jan 29, 2021

    @cyphar
    Contributor

    @Frederick888 As in O_APPEND doesn't work, or gives you an error? That sounds like a separate bug to me -- ZFS should work as a lowerdir for overlayfs and if it doesn't it's either a bug in overlayfs or ZFS.

  7. Frederick888 commented on Jan 29, 2021

    @Frederick888

    @cyphar When using tee -a it reports Invalid argument, e.g.

    $ zfs list | rg '/home'
    tank/data/home     50.0G   367G     38.8G  /home
    $ mkdir ~/lower
    
    $ pwd
    /tmp/test
    $ df -h .
    Filesystem      Size  Used Avail Use% Mounted on
    tmpfs            24G  308M   24G   2% /tmp
    $ mkdir upper work merged
    
    $ printf 'hello world\n' | tee ~/lower/test.txt
    hello world
    $ sudo mount -t overlay overlay -o lowerdir=/home/frederick/lower,upperdir=./upper,workdir=./work,redirect_dir=follow ./merged
    $ cat merged/test.txt
    hello world
    $ printf 'hello world\n' | tee -a merged/test.txt
    tee: merged/test.txt: Invalid argument
    hello world

    Similar when git pull, error message being e.g. error: cannot update the ref 'refs/remotes/origin/master': unable to append to '.git/logs/refs/remotes/origin/master': Invalid argument.

    I also tested the same thing using ext4 as lower dir and it all worked normally.

  8. cyphar commented on Jan 29, 2021

    @cyphar
    Contributor

    -EINVAL is definitely a weird response to get. I'll take a look -- it is possible it's related to the lack of renameat2 but that should only matter for upperdir not lowerdir...

  9. added a commit that references this issue on Feb 2, 2021
    f3e39eb
  10. added 4 commits that reference this issue on Apr 27, 2021
    b8ead7e
    d834fd6
    fc40669
    224d2af
  11. added a commit that references this issue on May 8, 2021
    fe373db
  12. added a commit that references this issue on Jan 19, 2022
  13. thoernle commented on Mar 2, 2023

    @thoernle

    This should be closed because OverlayFS support has already been merged in #9414, right?

  14. galaxy001 commented on Mar 2, 2023

    @galaxy001

    With zfs-dkms 2.1.9-1 and kernel 6.1.14-1-lts, I still got the error with podman:

    [22424.607969] overlayfs: upper fs does not support RENAME_WHITEOUT.
    [22424.608104] overlayfs: upper fs does not support file handles, falling back to index=off.
    [22424.608109] overlayfs: fs on '/home/galaxy/.local/share/containers/storage/overlay/l/ZH4GPIMNPLZLZ5T2J5WAUPB77S' does not support file handles, falling back to xino=off.
    
  15. satmandu commented on Mar 2, 2023

    @satmandu
    Contributor

    Overlayfs support is only in the master branch of openzfs at the moment. It should be in 2.2 when it gets released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: FeatureFeature request or new feature

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions