Skip to content

Commit 4d44306

Browse files
committed
fix: wipe disk by signatures
Fixes #12491 In (almost) all places we previously used `FastWipe`, use instead a helper which will try to discover filesystem/partition signatures, and wipe them. This fixes the issue when a partition re-created in the same place might already hit a scenario when the "old" filesystem is discovered in the same place. Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com> (cherry picked from commit 5127ef7)
1 parent cca4cd2 commit 4d44306

File tree

7 files changed

+79
-56
lines changed

7 files changed

+79
-56
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/siderolabs/go-blockdevice/v2/partitioning/gpt"
1818
"go.uber.org/zap"
1919

20+
"github.com/siderolabs/talos/internal/pkg/partition"
2021
"github.com/siderolabs/talos/pkg/machinery/resources/block"
2122
)
2223

@@ -101,7 +102,7 @@ func CreatePartition(ctx context.Context, logger *zap.Logger, diskPath string, v
101102

102103
defer partitionDev.Close() //nolint:errcheck
103104

104-
if err = partitionDev.FastWipe(); err != nil {
105+
if err = partition.WipeWithSignatures(partitionDev, partitionDevName, logger.Sugar().Debugf); err != nil {
105106
return CreatePartitionResult{}, xerrors.NewTaggedf[Retryable]("error wiping partition: %w", err)
106107
}
107108

internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,11 @@ func ResetSystemDisk(_ runtime.Sequence, data any) (runtime.TaskExecutionFunc, s
11251125

11261126
defer dev.Close() //nolint:errcheck
11271127

1128-
return dev.FastWipe()
1128+
if err = partition.WipeWithSignatures(dev, devPath, logger.Printf); err != nil {
1129+
return err
1130+
}
1131+
1132+
return nil
11291133
}(systemDiskPath); err != nil {
11301134
return fmt.Errorf("failed to wipe system disk %s: %w", systemDiskPath, err)
11311135
}
@@ -1163,7 +1167,11 @@ func ResetUserDisks(_ runtime.Sequence, data any) (runtime.TaskExecutionFunc, st
11631167

11641168
logger.Printf("wiping user disk %s", deviceName)
11651169

1166-
return dev.FastWipe()
1170+
if err = partition.WipeWithSignatures(dev, deviceName, logger.Printf); err != nil {
1171+
return err
1172+
}
1173+
1174+
return nil
11671175
}
11681176

11691177
for _, deviceName := range in.GetUserDisksToWipe() {

internal/app/maintenance/server.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/siderolabs/talos/internal/app/resources"
2828
storaged "github.com/siderolabs/talos/internal/app/storaged"
2929
"github.com/siderolabs/talos/internal/pkg/configuration"
30+
"github.com/siderolabs/talos/internal/pkg/partition"
3031
"github.com/siderolabs/talos/pkg/grpc/middleware/authz"
3132
"github.com/siderolabs/talos/pkg/machinery/api/machine"
3233
"github.com/siderolabs/talos/pkg/machinery/api/storage"
@@ -273,7 +274,7 @@ func (s *Server) Reset(ctx context.Context, in *machine.ResetRequest) (*machine.
273274

274275
defer dev.Close() //nolint:errcheck
275276

276-
if err = dev.FastWipe(); err != nil {
277+
if err = partition.WipeWithSignatures(dev, systemDisk.DevPath, log.Printf); err != nil {
277278
return nil, err
278279
}
279280

@@ -290,8 +291,7 @@ func (s *Server) Reset(ctx context.Context, in *machine.ResetRequest) (*machine.
290291

291292
log.Printf("wiping user disk %s", deviceName)
292293

293-
err = dev.FastWipe()
294-
if err != nil {
294+
if err = partition.WipeWithSignatures(dev, deviceName, log.Printf); err != nil {
295295
return nil, err
296296
}
297297
}

internal/app/storaged/server.go

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,17 @@ import (
1111
"log"
1212
"path/filepath"
1313
"slices"
14-
"strings"
1514

1615
"github.com/cosi-project/runtime/pkg/safe"
1716
"github.com/cosi-project/runtime/pkg/state"
18-
"github.com/siderolabs/gen/xslices"
19-
"github.com/siderolabs/go-blockdevice/v2/blkid"
2017
blockdev "github.com/siderolabs/go-blockdevice/v2/block"
2118
"github.com/siderolabs/go-blockdevice/v2/partitioning/gpt"
2219
"google.golang.org/grpc/codes"
2320
"google.golang.org/grpc/status"
2421
"google.golang.org/protobuf/types/known/emptypb"
2522

2623
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
24+
"github.com/siderolabs/talos/internal/pkg/partition"
2725
"github.com/siderolabs/talos/pkg/machinery/api/storage"
2826
"github.com/siderolabs/talos/pkg/machinery/resources/block"
2927
)
@@ -305,31 +303,8 @@ func (s *Server) wipeDevice(deviceName string, method storage.BlockDeviceWipeDes
305303
case storage.BlockDeviceWipeDescriptor_FAST:
306304
log.Printf("wiping block device %q with fast method", deviceName)
307305

308-
info, err := blkid.Probe(bd.File(), blkid.WithSkipLocking(true))
309-
if err == nil && info != nil && len(info.SignatureRanges) > 0 { // probe successful, wipe by signatures
310-
if err = bd.FastWipe(xslices.Map(info.SignatureRanges, func(r blkid.SignatureRange) blockdev.Range {
311-
return blockdev.Range(r)
312-
})...); err != nil {
313-
return status.Errorf(codes.Internal, "failed to wipe block device %q: %v", deviceName, err)
314-
}
315-
316-
log.Printf("block device %q wiped by ranges: %s",
317-
deviceName,
318-
strings.Join(
319-
xslices.Map(info.SignatureRanges,
320-
func(r blkid.SignatureRange) string {
321-
return fmt.Sprintf("%d-%d", r.Offset, r.Offset+r.Size)
322-
},
323-
),
324-
", ",
325-
),
326-
)
327-
} else { // probe failed, use default fast wipe
328-
if err = bd.FastWipe(); err != nil {
329-
return status.Errorf(codes.Internal, "failed to wipe block device %q: %v", deviceName, err)
330-
}
331-
332-
log.Printf("block device %q wiped with fast method", deviceName)
306+
if err = partition.WipeWithSignatures(bd, deviceName, log.Printf); err != nil {
307+
return status.Error(codes.Internal, err.Error())
333308
}
334309
default:
335310
return status.Errorf(codes.InvalidArgument, "unsupported wipe method %s", method)

internal/integration/api/update-hostname.go

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -137,31 +137,11 @@ func (suite *UpdateHostnameSuite) TestUpdateHostname() {
137137
}
138138

139139
func (suite *UpdateHostnameSuite) updateHostname(nodeCtx context.Context, newHostname string) {
140-
// [TODO]: this should be dropped once Terraform Provider is updated for Talos 1.12
141-
// do a negative patch removing v1alpha1 hostname-related config
142-
// In "normal" tests config is generated without hostname v1alpha1 parts,
143-
// but when the cluster is generated via Terraform, it uses outdated machinery and
144-
// generates config with v1alpha1 hostname parts.
145-
v1alpha1Drop := map[string]any{
146-
"machine": map[string]any{
147-
"network": map[string]any{
148-
"hostname": map[string]any{
149-
"$patch": "delete",
150-
},
151-
},
152-
"features": map[string]any{
153-
"stableHostname": map[string]any{
154-
"$patch": "delete",
155-
},
156-
},
157-
},
158-
}
159-
160140
hostnameConfig := network.NewHostnameConfigV1Alpha1()
161141
hostnameConfig.ConfigAuto = pointer.To(nethelpers.AutoHostnameKindOff)
162142
hostnameConfig.ConfigHostname = newHostname
163143

164-
suite.PatchMachineConfig(nodeCtx, v1alpha1Drop, hostnameConfig)
144+
suite.PatchMachineConfig(nodeCtx, hostnameConfig)
165145
}
166146

167147
func init() {

internal/pkg/partition/helpers.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
5+
package partition
6+
7+
import (
8+
"fmt"
9+
"strings"
10+
11+
"github.com/siderolabs/gen/xslices"
12+
"github.com/siderolabs/go-blockdevice/v2/blkid"
13+
"github.com/siderolabs/go-blockdevice/v2/block"
14+
)
15+
16+
// WipeWithSignatures wipes the given block device by its signatures (if available)
17+
// and falls back to fast wipe otherwise.
18+
//
19+
// The function assumes that the caller locked properly the block device (or the parent
20+
// device in case of partitions) before calling it.
21+
//
22+
// If non-nil log function is passed, it will be used to log the wipe process.
23+
func WipeWithSignatures(bd *block.Device, deviceName string, log func(string, ...any)) error {
24+
info, err := blkid.Probe(bd.File(), blkid.WithSkipLocking(true))
25+
if err == nil && info != nil && len(info.SignatureRanges) > 0 { // probe successful, wipe by signatures
26+
if err = bd.FastWipe(xslices.Map(info.SignatureRanges, func(r blkid.SignatureRange) block.Range {
27+
return block.Range(r)
28+
})...); err != nil {
29+
return fmt.Errorf("failed to wipe block device %q: %v", deviceName, err)
30+
}
31+
32+
if log != nil {
33+
log("block device %q wiped by ranges: %s",
34+
deviceName,
35+
strings.Join(
36+
xslices.Map(info.SignatureRanges,
37+
func(r blkid.SignatureRange) string {
38+
return fmt.Sprintf("%d-%d", r.Offset, r.Offset+r.Size)
39+
},
40+
),
41+
", ",
42+
),
43+
)
44+
}
45+
46+
return nil
47+
}
48+
49+
// probe failed or no signatures found, fast wipe
50+
if err = bd.FastWipe(); err != nil {
51+
return fmt.Errorf("failed to wipe block device %q: %v", deviceName, err)
52+
}
53+
54+
if log != nil {
55+
log("block device %q wiped with fast method", deviceName)
56+
}
57+
58+
return nil
59+
}

internal/pkg/partition/wipe.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func (v *VolumeWipeTarget) wipeWithParentLocked(log func(string, ...any)) error
107107

108108
log("wiping volume %q (%s)", v.GetLabel(), v.devName)
109109

110-
return bd.FastWipe()
110+
return WipeWithSignatures(bd, v.devName, log)
111111
}
112112

113113
func (v *VolumeWipeTarget) dropWithParentLocked(parentBd *block.Device, log func(string, ...any)) error {

0 commit comments

Comments
 (0)