fs.DiskUsage fails when a file is deleted during the walk (lstat/readdirent: no such file or directory)
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 78/100
Direzione di ricerca
Leggi fs/du_unix.go e fs/du_windows.go nelle posizioni citate delle callback, poi esamina come i relativi test di attraversamento coprono i percorsi che scompaiono durante l’attraversamento. Riproduci i casi ENOENT descritti nell’issue e verifica che entrambi i file li gestiscano, mentre una root mancante continui a restituire un errore. Il lavoro è completato quando il calcolo dello spazio su disco termina anche se alcune voci scompaiono durante l’attraversamento e continua a segnalare una root mancante.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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.
- Lingua principale
- Go
- Stelle
- 153
- Fork
- 74
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di containerd/continuity
-
Modernize repositoryAperta
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
containerd/continuity#277 · 1 commento ·
-
nerdctl commit taking long time possibly because of fs.Changes walking through all filesForse già presa @gogasca l’ha presa 257 giorni fa. Apertaenhancement
Difficoltà 4/5 3-5 giorni Idoneità per principianti 38/100
containerd/continuity#236 · 5 commenti ·
-
`continuity.context.Walk` assumes incorrect behavior for `os.Readlink`Forse già presa @sueun-dev l’ha presa 58 giorni fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 45/100
containerd/continuity#232 ·
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 35/100
containerd/continuity#226 · 1 commento ·
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
containerd/continuity#221 ·
Tutte le issue di containerd/continuity
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
I maintainer di solito rispondono entro 1 giorno
-
os: RawConn methods of a closed File return internal/poll.ErrFileClosing instead of ErrClosedAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
[Bug]: Bedrock invoke-with-response-stream reports `stop_reason: "end_turn"` for tool-use turnsAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
oalders/clodhopper#162 ·
I maintainer di solito rispondono entro 1 giorno
-
component/server severity/minor type/bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno