gvisor/images
Jamie Liu d846077628 Enable overlayfs_stale_read by default for runsc.
Linux 4.18 and later make reads and writes coherent between pre-copy-up and
post-copy-up FDs representing the same file on an overlay filesystem. However,
memory mappings remain incoherent:

- Documentation/filesystems/overlayfs.rst, "Non-standard behavior": "If a file
  residing on a lower layer is opened for read-only and then memory mapped with
  MAP_SHARED, then subsequent changes to the file are not reflected in the
  memory mapping."

- fs/overlay/file.c:ovl_mmap() passes through to the underlying FD without any
  management of coherence in the overlay.

- Experimentally on Linux 5.2:

```
$ cat mmap_cat_page.c
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

int main(int argc, char **argv) {
  if (argc < 2) {
    errx(1, "syntax: %s [FILE]", argv[0]);
  }
  const int fd = open(argv[1], O_RDONLY);
  if (fd < 0) {
    err(1, "open(%s)", argv[1]);
  }
  const size_t page_size = sysconf(_SC_PAGE_SIZE);
  void* page = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
  if (page == MAP_FAILED) {
    err(1, "mmap");
  }
  for (;;) {
    write(1, page, strnlen(page, page_size));
    if (getc(stdin) == EOF) {
      break;
    }
  }
  return 0;
}

$ gcc -O2 -o mmap_cat_page mmap_cat_page.c
$ mkdir lowerdir upperdir workdir overlaydir
$ echo old > lowerdir/file
$ sudo mount -t overlay -o "lowerdir=lowerdir,upperdir=upperdir,workdir=workdir" none overlaydir
$ ./mmap_cat_page overlaydir/file
old
^Z
[1]+  Stopped                 ./mmap_cat_page overlaydir/file
$ echo new > overlaydir/file
$ cat overlaydir/file
new
$ fg
./mmap_cat_page overlaydir/file

old
```

Therefore, while the VFS1 gofer client's behavior of reopening read FDs is only
necessary pre-4.18, replacing existing memory mappings (in both sentry and
application address spaces) with mappings of the new FD is required regardless
of kernel version, and this latter behavior is common to both VFS1 and VFS2.
Re-document accordingly, and change the runsc flag to enabled by default.

New test:
- Before this CL: https://source.cloud.google.com/results/invocations/5b222d2c-e918-4bae-afc4-407f5bac509b
- After this CL: https://source.cloud.google.com/results/invocations/f28c747e-d89c-4d8c-a461-602b33e71aab

PiperOrigin-RevId: 311361267
2020-05-13 10:53:37 -07:00
..
basic Standardize all Docker images. 2020-04-24 14:11:42 -07:00
default Adapt website to use g3doc sources and bazel. 2020-05-06 14:15:18 -07:00
hostoverlaytest Enable overlayfs_stale_read by default for runsc. 2020-05-13 10:53:37 -07:00
iptables Standardize all Docker images. 2020-04-24 14:11:42 -07:00
jekyll Merge pull request #2513 from amscanne:website-integrated 2020-05-12 12:55:23 -07:00
packetdrill Standardize all Docker images. 2020-04-24 14:11:42 -07:00
packetimpact Standardize all Docker images. 2020-04-24 14:11:42 -07:00
runtimes Standardize all Docker images. 2020-04-24 14:11:42 -07:00
BUILD Standardize all Docker images. 2020-04-24 14:11:42 -07:00
Makefile Standardize all Docker images. 2020-04-24 14:11:42 -07:00
README.md Standardize all Docker images. 2020-04-24 14:11:42 -07:00

README.md

Container Images

This directory contains all images used by tests.

Note that all these images must be pushed to the testing project hosted on [Google Container Registry][gcr]. This will happen automatically as part of continuous integration. This will speed up loading as images will not need to be built from scratch for each test run.

Image tooling is accessible via make, specifically via tools/images.mk.

Why make?

Make is used because it can bootstrap the default image, which contains bazel and all other parts of the toolchain.

Listing images

To list all images, use make list-all-images from the top-level directory.

Loading and referencing images

To build a specific image, use make load-<image> from the top-level directory. This will ensure that an image gvisor.dev/images/<image>:latest is available.

Images should always be referred to via the gvisor.dev/images canonical path. This tag exists only locally, but serves to decouple tests from the underlying image infrastructure.

The continuous integration system can either take fine-grained dependencies on single images via individual load targets, or pull all images via a single load-all-images invocation.

Adding new images

To add a new image, create a new directory under images containing a Dockerfile and any other files that the image requires. You may choose to add to an existing subdirectory if applicable, or create a new one.

All images will be tagged and memoized using a hash of the directory contents. As a result, every image should be made completely reproducible if possible. This means using fixed tags and fixed versions whenever feasible.

Notes that images should also be made architecture-independent if possible. The build scripts will handling loading the appropriate architecture onto the machine and tagging it with the single canonical tag.

Add a load-<image> dependency in the Makefile if the image is required for a particular set of tests. This target will pull the tag from the image repository if available.

Building and pushing images

All images can be built manually by running build-<image> and pushed using push-<image>. Note that you can also use build-all-images and push-all-images. Note that pushing will require appropriate permissions in the project.

The continuous integration system can either take fine-grained dependencies on individual push targets, or ensure all images are up-to-date with a single push-all-images invocation.