Skip to content

Filesystem under load occasionally reports mounted files as not existing #2870

@nwalters512

Description

@nwalters512
  • I have tried with the latest version of my channel (Stable or Edge)
  • I have submitted Diagnostics
  • I have included the Diagnostics ID in this Issue
  • macOS Version: 10.13.4 (17E199)

Expected behavior

When multiple processes are running in a tight loop that is checking if a file exists and reading it, the file should never be reported as not existing, assuming that the file is not accidentally deleted by another process.

Actual behavior

Node code (and likely other code as well, though I haven't yet tested other languages) that does what's described above will occasionally see that the file in question does not exist, even though it definitely does.

Information

This bug was observed when I was trying to compile the same EJS template in several worker processes at once. I observed that occasionally, one of the .ejs files that was included from the main template I was rendering would be reported as not existing, even though it definitely did. The included template was being used many times in the file, and so EJS was frequently checking if it existed and reading it.

Eventually, I determined that this failure only occurred if the following conditions
were met:

  • The code is being run inside a Docker container
  • Docker is being run on a Mac
  • The file that we're trying to check the existence of is on a mounted volume.

If either of those conditions are broken (the code was run directly on the host, the file exists in the image itself, or Docker is run on a Windows/Linux machine), then the bug disappears. For this reason, I believe the bug is with Docker for Mac, and not Node or EJS.

Diagnostic ID: 15D5E555-47BB-4C80-9B0C-BEFAF3F272AF

Docker for Mac: version: 18.03.1-ce-mac65 (dd2831d4b7421cf559a0881cc7a5fdebeb8c2b98) macOS: version 10.13.4 (build: 17E199) logs: /tmp/15D5E555-47BB-4C80-9B0C-BEFAF3F272AF/20180502-163929.tar.gz [OK] vpnkit [OK] vmnetd [OK] dns [OK] driver.amd64-linux [OK] virtualization VT-X [OK] app [OK] moby [OK] system [OK] moby-syslog [OK] kubernetes [OK] files [OK] env [OK] virtualization kern.hv_support [OK] osxfs [OK] moby-console [OK] logs [OK] docker-cli [OK] disk 

Steps to reproduce the behavior

I was able to reproduce this case with a simple program that spawns two children with the threads package. Each child repeatedly checks if a file exists and reads the file in a tight loop. On my Mac, I observe that the file sometimes appears to not exist.

Given that the reproducible case requires more than just a simple Dockerfile (several other files, dependencies, and a specific folder), I have set up a self-contained example in the repo at https://github.com/nwalters512/docker-file-bug. I've copy-pasted the Dockerfile and Node code here.

Dockerfile

FROM node:carbon WORKDIR /usr/src/app COPY package*.json ./ RUN npm install COPY . . CMD [ "node", "index.js" ] 

index.js

const Pool = require('threads').Pool; const pool = new Pool(); pool.run((opts, done) => { const fs = require('fs'); const file = '/volume/exist.data'; for (let i = 0; i < 100; i++) { if (!fs.existsSync(file)) { console.log('File does not exist!'); } else { console.log('File exists.') } fs.readFileSync(file); } done(); }); for (let i = 0; i < 2; i++) { pool.send('test'); } pool.on('finished', () => pool.killAll()); 

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions