volume ls: fix race that caused it to fail

If volume ls was called while another volume was removed at the right
time it could have failed with "no such volume" as we did not ignore
such error during listing. As we list things and this no longer exists
the correct thing is to ignore the error and continue like we do with
containers, pods, etc...

This was pretty easy to reproduce with these two commands running in
different terminals:
while :; do bin/podman volume create test && bin/podman volume rm test || break; done
while :; do bin/podman volume ls || break ; done

I have a slight feeling that this might solve #23913 but I am not to
sure there so I am not adding a Fixes here.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger 2024-11-06 12:11:23 +01:00
parent c0e24c6b60
commit 9a0c0b2eef
No known key found for this signature in database
GPG Key ID: EB145DD938A3CAF2
3 changed files with 9 additions and 23 deletions

View File

@ -60,6 +60,9 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) {
for _, v := range vols { for _, v := range vols {
mp, err := v.MountPoint() mp, err := v.MountPoint()
if err != nil { if err != nil {
if errors.Is(err, define.ErrNoSuchVolume) {
continue
}
utils.InternalServerError(w, err) utils.InternalServerError(w, err)
return return
} }

View File

@ -121,33 +121,13 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) {
return return
} }
volumeFilters := []libpod.VolumeFilter{} ic := abi.ContainerEngine{Libpod: runtime}
for filter, filterValues := range *filterMap { volumeConfigs, err := ic.VolumeList(r.Context(), entities.VolumeListOptions{Filter: *filterMap})
filterFunc, err := filters.GenerateVolumeFilters(filter, filterValues, runtime)
if err != nil { if err != nil {
utils.InternalServerError(w, err) utils.InternalServerError(w, err)
return return
} }
volumeFilters = append(volumeFilters, filterFunc)
}
vols, err := runtime.Volumes(volumeFilters...)
if err != nil {
utils.InternalServerError(w, err)
return
}
volumeConfigs := make([]*entities.VolumeListReport, 0, len(vols))
for _, v := range vols {
inspectOut, err := v.Inspect()
if err != nil {
utils.InternalServerError(w, err)
return
}
config := entities.VolumeConfigResponse{
InspectVolumeData: *inspectOut,
}
volumeConfigs = append(volumeConfigs, &entities.VolumeListReport{VolumeConfigResponse: config})
}
utils.WriteResponse(w, http.StatusOK, volumeConfigs) utils.WriteResponse(w, http.StatusOK, volumeConfigs)
} }

View File

@ -164,6 +164,9 @@ func (ic *ContainerEngine) VolumeList(ctx context.Context, opts entities.VolumeL
for _, v := range vols { for _, v := range vols {
inspectOut, err := v.Inspect() inspectOut, err := v.Inspect()
if err != nil { if err != nil {
if errors.Is(err, define.ErrNoSuchVolume) {
continue
}
return nil, err return nil, err
} }
config := entities.VolumeConfigResponse{ config := entities.VolumeConfigResponse{