fs.DiskUsage fails when a file is deleted during the walk (lstat/readdirent: no such file or directory)
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 78/100
Hướng nghiên cứu
Đọc fs/du_unix.go và fs/du_windows.go tại các vị trí callback được trích dẫn, sau đó kiểm tra các bài kiểm tra walk bao quát những đường dẫn biến mất trong quá trình duyệt như thế nào. Tái hiện các trường hợp ENOENT được mô tả trong issue và kiểm tra rằng cả hai tệp đều xử lý được chúng, trong khi root bị thiếu vẫn trả về lỗi. Công việc hoàn tất khi quá trình tính dung lượng đĩa kết thúc dù các mục biến mất giữa chừng khi duyệt, và vẫn báo lỗi khi root bị thiếu.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Problem
fs.DiskUsage fails if a file under the root is deleted while it walks. On Unix it is a filepath.Walk whose callback returns the error it receives (fs/du_unix.go#L68-L71):
if err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
if err != nil {
return err
}
filepath.Walk reads a directory and then lstats each entry. If the entry is removed between those two calls, the callback gets lstat …: no such file or directory and the whole usage call fails. A directory removed between being listed and being read fails with readdirent …: no such file or directory.
That is the normal case for the main caller. The containerd overlay snapshotter computes Usage of an active snapshot (a running container's writable layer) with fs.DiskUsage(ctx, upperPath), and running containers create and delete temp files all the time. In Docker (containerd image store), docker ps --size, docker ps --format '{{json .}}' and docker system df then fail:
Error response from daemon: snapshotter.Usage failed for db1ad9bf…: lstat /var/lib/docker/containerd/daemon/io.containerd.snapshotter.v1.overlayfs/snapshots/25/fs/tmp/cc/f17: no such file or directory
Error response from daemon: snapshotter.Usage failed for db1ad9bf…: readdirent /var/lib/docker/containerd/daemon/io.containerd.snapshotter.v1.overlayfs/snapshots/25/fs/tmp/cc: no such file or directory
Reproduce
With Docker on the containerd image store (continuity v0.5.0 via containerd v2.4.1, Docker 29.9.0):
docker run -d --name churn alpine:3.20 sh -c 'while true; do mkdir -p /tmp/cc; for i in $(seq 300); do : > /tmp/cc/f$i; done; rm -rf /tmp/cc; done'
sleep 2
for i in $(seq 50); do docker ps -a --size >/dev/null 2>&1 || echo fail; done | wc -l # 16 of 50 failed
docker rm -f churn
Without Docker: this Go program copies the diskUsage walk, runs it while a goroutine creates and removes 300 files in a subdirectory, and compares it with the fix below (Go 1.27.1, Linux 6.8, ext4):
continuity v0.5.0 walk: failed 1060/2000 map[lstat <path>: no such file or directory:1050 readdirent <path>: no such file or directory:10]
skip-ENOENT walk: failed 0/2000 map[]
missing root still fails: true
Suggested fix
A disk-usage walk is a point-in-time estimate, so an entry that disappears mid-walk has no size to count. Skip it instead of failing:
if err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
if err != nil {
if os.IsNotExist(err) && path != root {
return nil // removed while walking; it no longer uses space
}
return err
}
This also covers the directory case: when reading a directory fails, filepath.Walk passes that error to the callback for the directory, and returning nil skips the directory (the readdirent error is an *os.PathError wrapping ENOENT, so os.IsNotExist matches it). Keep failing if root itself is missing, so a wrong path is still reported.
fs/du_windows.go has the same callback and needs the same change.
Workarounds
Callers can avoid the walk when they don't need sizes: docker ps with explicit --format fields or --size=false (docker/cli#4067), or GET /system/df?type=image for image usage. A caller that needs the size can retry on ENOENT.
Related
- Docker: the daemon fails the whole container list on this error (the graphdriver store logs it and reports
-1). - The same error in other projects: ptone/scion#1867, ptone/scion#1864, openzim/zimfarm#1591, link-assistant/hive-mind#3000.
- containerd/nerdctl#3027: snapshotter
Usagecalls are expensive with many objects.
- Ngôn ngữ chính
- Go
- Star
- 153
- Fork
- 74
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của containerd/continuity
-
Modernize repositoryĐang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
containerd/continuity#277 · 1 bình luận ·
-
nerdctl commit taking long time possibly because of fs.Changes walking through all filesCó thể đã có người làm @gogasca đã nhận 257 ngày trước. Đang mởenhancement
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 38/100
containerd/continuity#236 · 5 bình luận ·
-
`continuity.context.Walk` assumes incorrect behavior for `os.Readlink`Có thể đã có người làm @sueun-dev đã nhận 58 ngày trước. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 45/100
containerd/continuity#232 ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
containerd/continuity#226 · 1 bình luận ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
containerd/continuity#221 ·
Tất cả issue của containerd/continuity
Issue tương tự
-
docs: clarify gh api -f vs -F and @-file expansion in the gh skillCó thể đã có người làm @MatiasOlivera đã nhận hôm nay. Đang mởenhancement
Độ khó 2/5 Nửa ngày Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
aws/aws-advanced-go-wrapper#612 ·
-
Say in the changelog that the text-index update cannot be rolled backCó thể đã có người làm @praetorianer777 đã nhận hôm nay. Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
praetorianer777/GoTome#275 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
SAP/crossplane-provider-btp#1118 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
benchmark: `make setup` fails because audit-exporter builds with Go 1.25.0 while go.mod requires 1.26.0Có thể đã có người làm @xsvm đã nhận hôm nay. Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 84/100
volcano-sh/volcano#6097 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày