diff --git a/cmd/installer/pkg/install/manifest.go b/cmd/installer/pkg/install/manifest.go index afa152ceec..945f9b0dfe 100644 --- a/cmd/installer/pkg/install/manifest.go +++ b/cmd/installer/pkg/install/manifest.go @@ -39,6 +39,8 @@ type Device struct { ResetPartitionTable bool Zero bool + + SkipOverlayMountsCheck bool } // NewManifest initializes and returns a Manifest. @@ -95,6 +97,8 @@ func NewManifest(label string, sequence runtime.Sequence, bootPartitionFound boo ResetPartitionTable: opts.Force, Zero: opts.Zero, + + SkipOverlayMountsCheck: sequence == runtime.SequenceNoop, } // Initialize any slices we need. Note that a boot partition is not @@ -170,6 +174,8 @@ func (m *Manifest) Execute() (err error) { } // checkMounts verifies that no active mounts in any mount namespace exist for the device. +// +//nolint:gocyclo func (m *Manifest) checkMounts(device Device) error { matches, err := filepath.Glob("/proc/*/mountinfo") if err != nil { @@ -198,6 +204,22 @@ func (m *Manifest) checkMounts(device Device) error { continue } + if !device.SkipOverlayMountsCheck && fields[len(fields)-2] == "overlay" { + // parsing options (last column) in the overlay mount line which looks like: + // 163 70 0:52 /apid / ro,relatime - overlay overlay rw,lowerdir=/opt,upperdir=/var/system/overlays/opt-diff,workdir=/var/system/overlays/opt-workdir + + options := strings.Split(fields[len(fields)-1], ",") + + for _, option := range options { + parts := strings.SplitN(option, "=", 2) + if len(parts) == 2 { + if strings.HasPrefix(parts[1], "/var/") { + return fmt.Errorf("found overlay mount in %q: %s", path, scanner.Text()) + } + } + } + } + if fields[len(fields)-2] == device.Device { return fmt.Errorf("found active mount in %q for %q: %s", path, device.Device, scanner.Text()) } diff --git a/cmd/installer/pkg/install/manifest_test.go b/cmd/installer/pkg/install/manifest_test.go index 76855e5be7..026040f9db 100644 --- a/cmd/installer/pkg/install/manifest_test.go +++ b/cmd/installer/pkg/install/manifest_test.go @@ -233,6 +233,11 @@ func (suite *manifestSuite) TestExecuteManifestClean() { }) suite.Require().NoError(err) + // in the tests overlay mounts should be ignored + dev := manifest.Devices[suite.loopbackDevice.Name()] + dev.SkipOverlayMountsCheck = true + manifest.Devices[suite.loopbackDevice.Name()] = dev + suite.Assert().NoError(manifest.Execute()) suite.verifyBlockdevice(manifest, "", "A", false, false) @@ -249,6 +254,11 @@ func (suite *manifestSuite) TestExecuteManifestForce() { }) suite.Require().NoError(err) + // in the tests overlay mounts should be ignored + dev := manifest.Devices[suite.loopbackDevice.Name()] + dev.SkipOverlayMountsCheck = true + manifest.Devices[suite.loopbackDevice.Name()] = dev + suite.Assert().NoError(manifest.Execute()) suite.verifyBlockdevice(manifest, "", "A", false, false) @@ -264,6 +274,11 @@ func (suite *manifestSuite) TestExecuteManifestForce() { }) suite.Require().NoError(err) + // in the tests overlay mounts should be ignored + dev = manifest.Devices[suite.loopbackDevice.Name()] + dev.SkipOverlayMountsCheck = true + manifest.Devices[suite.loopbackDevice.Name()] = dev + suite.Assert().NoError(manifest.Execute()) suite.verifyBlockdevice(manifest, "A", "B", true, false) @@ -280,6 +295,11 @@ func (suite *manifestSuite) TestExecuteManifestPreserve() { }) suite.Require().NoError(err) + // in the tests overlay mounts should be ignored + dev := manifest.Devices[suite.loopbackDevice.Name()] + dev.SkipOverlayMountsCheck = true + manifest.Devices[suite.loopbackDevice.Name()] = dev + suite.Assert().NoError(manifest.Execute()) suite.verifyBlockdevice(manifest, "", "A", false, false) @@ -294,6 +314,11 @@ func (suite *manifestSuite) TestExecuteManifestPreserve() { }) suite.Require().NoError(err) + // in the tests overlay mounts should be ignored + dev = manifest.Devices[suite.loopbackDevice.Name()] + dev.SkipOverlayMountsCheck = true + manifest.Devices[suite.loopbackDevice.Name()] = dev + suite.Assert().NoError(manifest.Execute()) suite.verifyBlockdevice(manifest, "A", "B", true, true) diff --git a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go index 2840e9955b..148b6e169f 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go @@ -808,8 +808,9 @@ func partitionAndFormatDisks(logger *log.Logger, r runtime.Runtime) error { } m.Devices[disk.Device()] = installer.Device{ - Device: disk.Device(), - ResetPartitionTable: true, + Device: disk.Device(), + ResetPartitionTable: true, + SkipOverlayMountsCheck: true, } for _, part := range disk.Partitions() {