Skip to content

Commit c277d01

Browse files
committed
fix: ignore volumes in wave calculation without provisioning
The waves are used in the volume manager to order provisioning of volumes on disk (allocating a partition, etc.), so that system volumes are done first, and only then user volumes are allocated. The wave calculation logic had a bug though with volumes which don't have provisioning instructions (they can be only located), e.g. the `IMAGECACHE-ISO` volume which is only located, but never provisioned. Such volume (if the ISO is missing) will always stay in `missing` status, which is fine, but it shouldn't block the provisioning of the next waves. Moreover, if `.provisioning` is not set, reading wave from it doesn't make sense, as it will always be zero (unset). Also sort the volume configs accordingly, volumes without provisioning instructions should be always processed first, they don't block others. Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com> (cherry picked from commit 33b5b25)
1 parent f90af88 commit c277d01

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

internal/app/machined/pkg/controllers/block/internal/volumes/volumes.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"math"
1111

1212
"github.com/siderolabs/gen/optional"
13+
"github.com/siderolabs/gen/value"
1314

1415
"github.com/siderolabs/talos/internal/pkg/encryption"
1516
blockpb "github.com/siderolabs/talos/pkg/machinery/api/resource/definitions/block"
@@ -18,7 +19,12 @@ import (
1819

1920
// CompareVolumeConfigs compares two volume configs in the proposed order of provisioning.
2021
func CompareVolumeConfigs(a, b *block.VolumeConfig) int {
21-
// first, sort by wave, smaller wave first
22+
// first, sort volumes without provisioning instructions first, as they don't block provisioning of other volumes
23+
if c := cmpBool(!value.IsZero(a.TypedSpec().Provisioning), !value.IsZero(b.TypedSpec().Provisioning)); c != 0 {
24+
return c
25+
}
26+
27+
// second, sort by wave, smaller wave first
2228
if c := cmp.Compare(a.TypedSpec().Provisioning.Wave, b.TypedSpec().Provisioning.Wave); c != 0 {
2329
return c
2430
}

internal/app/machined/pkg/controllers/block/internal/volumes/volumes_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ func TestCompareVolumeConfigs(t *testing.T) {
2424

2525
expected int
2626
}{
27+
{
28+
name: "no provisioning instructions",
29+
30+
a: &block.VolumeConfigSpec{},
31+
b: &block.VolumeConfigSpec{
32+
Provisioning: block.ProvisioningSpec{
33+
Wave: block.WaveSystemDisk,
34+
},
35+
},
36+
37+
expected: -1,
38+
},
2739
{
2840
name: "different wave",
2941

@@ -35,6 +47,9 @@ func TestCompareVolumeConfigs(t *testing.T) {
3547
b: &block.VolumeConfigSpec{
3648
Provisioning: block.ProvisioningSpec{
3749
Wave: block.WaveUserVolumes,
50+
FilesystemSpec: block.FilesystemSpec{
51+
Type: block.FilesystemTypeEXT4,
52+
},
3853
},
3954
},
4055

internal/app/machined/pkg/controllers/block/volume_manager.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/cosi-project/runtime/pkg/safe"
1919
"github.com/cosi-project/runtime/pkg/state"
2020
"github.com/siderolabs/gen/optional"
21+
"github.com/siderolabs/gen/value"
2122
"github.com/siderolabs/gen/xerrors"
2223
"github.com/siderolabs/gen/xslices"
2324
"go.uber.org/zap"
@@ -403,7 +404,9 @@ func (ctrl *VolumeManagerController) Run(ctx context.Context, r controller.Runti
403404
volumeStatus.TypedSpec().PreFailPhase = block.VolumePhase(0)
404405
}
405406

406-
if volumeStatus.TypedSpec().Phase != block.VolumePhaseReady {
407+
// if the volume is not ready yet, we can consider the wave not fully provisioned, so the next wave can't start provisioning either
408+
// but if the volume doesn't have provisioning instructions, we don't block on it being ready
409+
if volumeStatus.TypedSpec().Phase != block.VolumePhaseReady && !value.IsZero(vc.TypedSpec().Provisioning) {
407410
fullyProvisionedWave = vc.TypedSpec().Provisioning.Wave - 1
408411
}
409412

0 commit comments

Comments
 (0)