1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/daemon/graphdriver
Kir Kolyshkin ae431b10a9 aufs: retry auplink flush
Running a bundled aufs benchmark sometimes results in this warning:

> WARN[0001] Couldn't run auplink before unmount /tmp/aufs-tests/aufs/mnt/XXXXX  error="exit status 22" storage-driver=aufs

If we take a look at what aulink utility produces on stderr, we'll see:

> auplink:proc_mnt.c:96: /tmp/aufs-tests/aufs/mnt/XXXXX: Invalid argument

and auplink exits with exit code of 22 (EINVAL).

Looking into auplink source code, what happens is it tries to find a
record in /proc/self/mounts corresponding to the mount point (by using
setmntent()/getmntent_r() glibc functions), and it fails.

Some manual testing, as well as runtime testing with lots of printf
added on mount/unmount, as well as calls to check the superblock fs
magic on mount point (as in graphdriver.Mounted(graphdriver.FsMagicAufs, target)
confirmed that this record is in fact there, but sometimes auplink
can't find it. I was also able to reproduce the same error (inability
to find a mount in /proc/self/mounts that should definitely be there)
using a small C program, mocking what `auplink` does:

```c
 #include <stdio.h>
 #include <err.h>
 #include <mntent.h>
 #include <string.h>
 #include <stdlib.h>

int main(int argc, char **argv)
{
	FILE *fp;
	struct mntent m, *p;
	char a[4096];
	char buf[4096 + 1024];
	int found =0, lines = 0;

	if (argc != 2) {
		fprintf(stderr, "Usage: %s <mountpoint>\n", argv[0]);
		exit(1);
	}

	fp = setmntent("/proc/self/mounts", "r");
	if (!fp) {
		err(1, "setmntent");
	}
	setvbuf(fp, a, _IOLBF, sizeof(a));
	while ((p = getmntent_r(fp, &m, buf, sizeof(buf)))) {
		lines++;
		if (!strcmp(p->mnt_dir, argv[1])) {
			found++;
		}
	}
	printf("found %d entries for %s (%d lines seen)\n", found, argv[1], lines);
	return !found;
}
```

I have also wrote a few other C proggies -- one that reads
/proc/self/mounts directly, one that reads /proc/self/mountinfo instead.
They are also prone to the same occasional error.

It is not perfectly clear why this happens, but so far my best theory
is when a lot of mounts/unmounts happen in parallel with reading
contents of /proc/self/mounts, sometimes the kernel fails to provide
continuity (i.e. it skips some part of file or mixes it up in some
other way). In other words, this is a kernel bug (which is probably
hard to fix unless some other interface to get a mount entry is added).

Now, there is no real fix, and a workaround I was able to come up
with is to retry when we got EINVAL. It usually works on the second
attempt, although I've once seen it took two attempts to go through.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2019-05-21 10:58:59 -07:00
..
aufs aufs: retry auplink flush 2019-05-21 10:58:59 -07:00
btrfs pkg/mount: wrap mount/umount errors 2018-12-10 20:07:02 -08:00
copy Graphdriver: fix "device" mode not being detected if "character-device" bit is set 2019-02-20 11:08:58 +01:00
devmapper pkg/mount: wrap mount/umount errors 2018-12-10 20:07:02 -08:00
graphtest Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
lcow LCOW: Add SIDs to layer.vhd at creation 2019-03-21 13:12:17 -07:00
overlay Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
overlay2 change hard code: add some overlay2 constant to replace the hard code. 2019-04-02 10:57:13 +08:00
overlayutils Add additional message when backendfs is extfs without d_type support 2018-05-18 10:32:47 +08:00
quota Minor error cleanups in projectquota 2019-03-13 23:39:38 +01:00
register Add canonical import comment 2018-02-05 16:51:57 -05:00
vfs add vfs quota for daemon storage-opts 2019-03-11 21:07:29 +08:00
windows Remove duplicated words in daemon files 2018-10-06 00:06:38 +08:00
zfs pkg/mount: wrap mount/umount errors 2018-12-10 20:07:02 -08:00
counter.go graphdriver: Fix RefCounter memory leak 2018-02-09 10:26:06 +08:00
driver.go Deprecate AuFS storage driver, and add warning 2018-10-26 18:41:46 +02:00
driver_freebsd.go Add canonical import comment 2018-02-05 16:51:57 -05:00
driver_linux.go Add canonical import comment 2018-02-05 16:51:57 -05:00
driver_test.go Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
driver_unsupported.go Add canonical import comment 2018-02-05 16:51:57 -05:00
driver_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
errors.go Add canonical import comment 2018-02-05 16:51:57 -05:00
fsdiff.go Add layer id to NaiveDiffDriver untar timing log 2018-10-05 16:28:40 -07:00
plugin.go Move plugin client to separate interface 2018-05-30 15:22:10 -04:00
proxy.go Move plugin client creation to the extension point 2018-05-25 15:18:53 -04:00