podman pod stats: fix race when ctr process exits

Like commit 55749af0c7 but for podman *pod* stats not the normal podman
stats. We must ignore ErrCtrStopped here as well as this will happen
when the container process exited.

While at it remove a useless argument from the function as it was always
nil and restructure the logic flow to make it easier to read.

Fixes #23334

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger
2024-07-22 10:16:18 +02:00
parent 003527fedc
commit 55b6e4c3e8
2 changed files with 9 additions and 9 deletions

View File

@ -459,7 +459,7 @@ type PodContainerStats struct {
} }
// GetPodStats returns the stats for each of its containers // GetPodStats returns the stats for each of its containers
func (p *Pod) GetPodStats(previousContainerStats map[string]*define.ContainerStats) (map[string]*define.ContainerStats, error) { func (p *Pod) GetPodStats() (map[string]*define.ContainerStats, error) {
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
@ -472,16 +472,16 @@ func (p *Pod) GetPodStats(previousContainerStats map[string]*define.ContainerSta
} }
newContainerStats := make(map[string]*define.ContainerStats) newContainerStats := make(map[string]*define.ContainerStats)
for _, c := range containers { for _, c := range containers {
newStats, err := c.GetContainerStats(previousContainerStats[c.ID()]) newStats, err := c.GetContainerStats(nil)
// If the container wasn't running, don't include it if err != nil {
// but also suppress the error // If the container wasn't running ignore it
if err != nil && !errors.Is(err, define.ErrCtrStateInvalid) { if errors.Is(err, define.ErrCtrStateInvalid) || errors.Is(err, define.ErrCtrStopped) {
continue
}
return nil, err return nil, err
} }
if err == nil {
newContainerStats[c.ID()] = newStats newContainerStats[c.ID()] = newStats
} }
}
return newContainerStats, nil return newContainerStats, nil
} }

View File

@ -38,7 +38,7 @@ func (ic *ContainerEngine) PodStats(ctx context.Context, namesOrIds []string, op
func (ic *ContainerEngine) podsToStatsReport(pods []*libpod.Pod) ([]*entities.PodStatsReport, error) { func (ic *ContainerEngine) podsToStatsReport(pods []*libpod.Pod) ([]*entities.PodStatsReport, error) {
reports := []*entities.PodStatsReport{} reports := []*entities.PodStatsReport{}
for i := range pods { // Access by index to prevent potential loop-variable leaks. for i := range pods { // Access by index to prevent potential loop-variable leaks.
podStats, err := pods[i].GetPodStats(nil) podStats, err := pods[i].GetPodStats()
if err != nil { if err != nil {
// pod was removed, skip it // pod was removed, skip it
if errors.Is(err, define.ErrNoSuchPod) { if errors.Is(err, define.ErrNoSuchPod) {