Browse code

daemon: disk-usage: fix incorrect key for singleflight

commit a69abdd90db3fc471c975d7cd9146d3c5ec6d30b introduced a "verbose"
option for the disk-usage endpoint, which allowed omitting the items
to be included in the results.

However, it did not take into account that a singleflight is used to
allow sharing the results between requests; this means that a request
made while another request is already in flight could share the wrong
results, and either get "verbose" or "non-verbose", depending on the
request already in flight.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2025/11/08 05:21:32
Showing 2 changed files
... ...
@@ -131,9 +131,9 @@ type Daemon struct {
131 131
 	seccompProfile     []byte
132 132
 	seccompProfilePath string
133 133
 
134
-	usageContainers singleflight.Group[struct{}, *backend.ContainerDiskUsage]
135
-	usageImages     singleflight.Group[struct{}, *backend.ImageDiskUsage]
136
-	usageVolumes    singleflight.Group[struct{}, *backend.VolumeDiskUsage]
134
+	usageContainers singleflight.Group[bool, *backend.ContainerDiskUsage]
135
+	usageImages     singleflight.Group[bool, *backend.ImageDiskUsage]
136
+	usageVolumes    singleflight.Group[bool, *backend.VolumeDiskUsage]
137 137
 	usageLayer      singleflight.Group[struct{}, int64]
138 138
 
139 139
 	pruneRunning atomic.Bool
... ...
@@ -16,7 +16,7 @@ import (
16 16
 // containerDiskUsage obtains information about container data disk usage
17 17
 // and makes sure that only one calculation is performed at the same time.
18 18
 func (daemon *Daemon) containerDiskUsage(ctx context.Context, verbose bool) (*backend.ContainerDiskUsage, error) {
19
-	res, _, err := daemon.usageContainers.Do(ctx, struct{}{}, func(ctx context.Context) (*backend.ContainerDiskUsage, error) {
19
+	res, _, err := daemon.usageContainers.Do(ctx, verbose, func(ctx context.Context) (*backend.ContainerDiskUsage, error) {
20 20
 		// Retrieve container list
21 21
 		containers, err := daemon.Containers(ctx, &backend.ContainerListOptions{
22 22
 			Size: true,
... ...
@@ -60,7 +60,7 @@ func (daemon *Daemon) containerDiskUsage(ctx context.Context, verbose bool) (*ba
60 60
 // imageDiskUsage obtains information about image data disk usage from image service
61 61
 // and makes sure that only one calculation is performed at the same time.
62 62
 func (daemon *Daemon) imageDiskUsage(ctx context.Context, verbose bool) (*backend.ImageDiskUsage, error) {
63
-	du, _, err := daemon.usageImages.Do(ctx, struct{}{}, func(ctx context.Context) (*backend.ImageDiskUsage, error) {
63
+	du, _, err := daemon.usageImages.Do(ctx, verbose, func(ctx context.Context) (*backend.ImageDiskUsage, error) {
64 64
 		// Get all top images with extra attributes
65 65
 		images, err := daemon.imageService.Images(ctx, imagebackend.ListOptions{
66 66
 			Filters:    filters.NewArgs(),
... ...
@@ -106,7 +106,7 @@ func (daemon *Daemon) imageDiskUsage(ctx context.Context, verbose bool) (*backen
106 106
 // localVolumesSize obtains information about volume disk usage from volumes service
107 107
 // and makes sure that only one size calculation is performed at the same time.
108 108
 func (daemon *Daemon) localVolumesSize(ctx context.Context, verbose bool) (*backend.VolumeDiskUsage, error) {
109
-	volumes, _, err := daemon.usageVolumes.Do(ctx, struct{}{}, func(ctx context.Context) (*backend.VolumeDiskUsage, error) {
109
+	volumes, _, err := daemon.usageVolumes.Do(ctx, verbose, func(ctx context.Context) (*backend.VolumeDiskUsage, error) {
110 110
 		volumes, err := daemon.volumes.LocalVolumesSize(ctx)
111 111
 		if err != nil {
112 112
 			return nil, err