-
Notifications
You must be signed in to change notification settings - Fork 9
VirtioFS bind mount case-insensitive directory listing behavior #251
Description
Bug report
Note
Imported from docker/for-mac#7218 because the issue is still active and appears to have fallen through the cracks during the sunset of https://github.com/docker/for-mac.
Full credit to @ummcheng for the original report! 🙇
Bug description
Attempting to list a directory fails immediately after listing with a case-insensitive name from the same process. For example, if I have a directory named a, calling ls a and ls A separately will succeed, but ls a A fails with can't open 'a': No such file or directory when a is the directory's actual, case-sensitive name. Variations on the ordering and number of attempts (e.g. ls a A a a) can result in either a or A succeeding or failing.
This behavior is only observed when a bind mount is used and VirtioFS is selected, not gRPC FUSE.
Reproduction steps
The minimal reproducible example with ls is:
From host:
$ mkdir test && cd test
$ docker run --interactive --tty --rm --mount type=bind,src=$(pwd),dst=/test --workdir /test busybox shIn container:
/test # mkdir a
/test # ls .
a
/test # ls a
/test # ls A
/test # ls . a
.:
a
a:
/test # ls . A
.:
a
A:
ls: can't open 'A': No such file or directory
/test # ls a A
A:
a:
ls: can't open 'a': No such file or directory
/test # ls a A a
A:
ls: can't open 'A': No such file or directory
a:
ls: can't open 'a': No such file or directory
a:This is also reproducible with Python and Node images and REPLs:
From host:
$ docker run --interactive --tty --rm --mount type=bind,src=$(pwd),dst=/test --workdir /test python shIn container:
# mkdir a
# python
Python 3.12.2 (main, Mar 12 2024, 08:01:18) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from os import listdir
>>> listdir("./a")
[]
>>> listdir("./A")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: './A'
>>> listdir("./a")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: './a'
>>> listdir("./a")
[]
>>> listdir("./A")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: './A'
>>> listdir("./A")
[]From host:
$ docker run --interactive --tty --rm --mount type=bind,src=$(pwd),dst=/test --workdir /test node shIn container:
# mkdir a
# node
Welcome to Node.js v21.7.1.
Type ".help" for more information.
> fs.readdirSync("./a")
[]
> fs.readdirSync("./A")
Uncaught Error: ENOENT: no such file or directory, scandir './A'
at Object.readdirSync (node:fs:1508:26) {
errno: -2,
code: 'ENOENT',
syscall: 'scandir',
path: './A'
}
> fs.readdirSync("./A")
[]
> fs.readdirSync("./a")
Uncaught Error: ENOENT: no such file or directory, scandir './a'
at Object.readdirSync (node:fs:1508:26) {
errno: -2,
code: 'ENOENT',
syscall: 'scandir',
path: './a'
}
> fs.readdirSync("./a")
[]Platform
macOS
Version information
Client:
Cloud integration: v1.0.35+desktop.11
Version: 25.0.3
API version: 1.44
Go version: go1.21.6
Git commit: 4debf41
Built: Tue Feb 6 21:13:26 2024
OS/Arch: darwin/arm64
Context: desktop-linux
Server: Docker Desktop 4.28.0 (139021)
Engine:
Version: 25.0.3
API version: 1.44 (minimum version 1.24)
Go version: go1.21.6
Git commit: f417435
Built: Tue Feb 6 21:14:22 2024
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: 1.6.28
GitCommit: ae07eda36dd25f8a1b98dfbf587313b99c0190bb
runc:
Version: 1.1.12
GitCommit: v1.1.12-0-g51d5e94
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Client:
Version: 25.0.3
Context: desktop-linux
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.12.1-desktop.4
Path: /Users/cheng/.docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.24.6-desktop.1
Path: /Users/cheng/.docker/cli-plugins/docker-compose
debug: Get a shell into any image or container. (Docker Inc.)
Version: 0.0.24
Path: /Users/cheng/.docker/cli-plugins/docker-debug
dev: Docker Dev Environments (Docker Inc.)
Version: v0.1.0
Path: /Users/cheng/.docker/cli-plugins/docker-dev
extension: Manages Docker extensions (Docker Inc.)
Version: v0.2.22
Path: /Users/cheng/.docker/cli-plugins/docker-extension
feedback: Provide feedback, right in your terminal! (Docker Inc.)
Version: v1.0.4
Path: /Users/cheng/.docker/cli-plugins/docker-feedback
init: Creates Docker-related starter files for your project (Docker Inc.)
Version: v1.0.1
Path: /Users/cheng/.docker/cli-plugins/docker-init
sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.)
Version: 0.6.0
Path: /Users/cheng/.docker/cli-plugins/docker-sbom
scout: Docker Scout (Docker Inc.)
Version: v1.5.0
Path: /Users/cheng/.docker/cli-plugins/docker-scout
WARNING: Plugin "/Users/cheng/.docker/cli-plugins/docker-scan" is not valid: failed to fetch metadata: fork/exec /Users/cheng/.docker/cli-plugins/docker-scan: no such file or directory
Server:
Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 7
Server Version: 25.0.3
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: ae07eda36dd25f8a1b98dfbf587313b99c0190bb
runc version: v1.1.12-0-g51d5e94
init version: de40ad0
Security Options:
seccomp
Profile: unconfined
cgroupns
Kernel Version: 6.6.16-linuxkit
Operating System: Docker Desktop
OSType: linux
Architecture: aarch64
CPUs: 4
Total Memory: 5.791GiB
Name: docker-desktop
ID: 00b44509-fe81-4d3c-b675-3f565ae428e1
Docker Root Dir: /var/lib/docker
Debug Mode: false
HTTP Proxy: http.docker.internal:3128
HTTPS Proxy: http.docker.internal:3128
No Proxy: hubproxy.docker.internal
Experimental: false
Insecure Registries:
hubproxy.docker.internal:5555
127.0.0.0/8
Live Restore Enabled: false
WARNING: daemon is not using the default seccomp profileDiagnostics ID
CE4E8E1C-9163-4476-B178-2F6A87F30FC6/20240315120144