fs.DiskUsage fails when a file is deleted during the walk (lstat/readdirent: no such file or directory)
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 78/100
Línea de trabajo
Lee fs/du_unix.go y fs/du_windows.go en las ubicaciones citadas de las callbacks y luego revisa cómo sus pruebas de recorrido cubren las rutas que desaparecen durante el recorrido. Reproduce los casos ENOENT descritos en el issue y comprueba que ambos archivos los gestionan, mientras que una raíz inexistente sigue devolviendo un error. La tarea estará terminada cuando el cálculo del uso del disco finalice aunque las entradas desaparezcan durante el recorrido y siga informando de una raíz inexistente.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Go
- Estrellas
- 153
- Forks
- 74
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de containerd/continuity
-
Modernize repositoryAbierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
containerd/continuity#277 · 1 comentario ·
-
nerdctl commit taking long time possibly because of fs.Changes walking through all filesPosiblemente ocupada @gogasca la tomó hace 258 días. Abiertoenhancement
Dificultad 4/5 3-5 días Aptitud para principiantes 38/100
containerd/continuity#236 · 5 comentarios ·
-
`continuity.context.Walk` assumes incorrect behavior for `os.Readlink`Posiblemente ocupada @sueun-dev la tomó hace 59 días. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
containerd/continuity#232 ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
containerd/continuity#226 · 1 comentario ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
containerd/continuity#221 ·
Todos los issues de containerd/continuity
Issues similares
-
documentation hacktoberfest priority: low skill: good first issue status: ready for dev
Dificultad 2/5 Medio día Aptitud para principiantes 85/100
hyperledger-labs/fabric-smart-client#2142 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
numberly/vault-db-injector#107 ·
Los mantenedores suelen responder en 1 día
-
area/import kind/bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
[DOC] Wrong sg_egress_ports range in the Terraform Databricks Guide for AWS Hub & Spoke with Network FirewallPosiblemente ocupada @akhil9tiet la tomó hoy. Abiertodocs
Dificultad 1/5 Menos de una hora Aptitud para principiantes 72/100
databricks/terraform-provider-databricks#6080 · 1 comentario ·
Los mantenedores suelen responder en 3 días
-
kind/documentation
Dificultad 2/5 1-3 horas Aptitud para principiantes 80/100
kubernetes-sigs/dra-driver-nvidia-gpu#1569 ·
Los mantenedores suelen responder en 1 día