Skip to content

Commit

Permalink
fix: handle skipped mounts correctly
Browse files Browse the repository at this point in the history
If the mount is skipped, we shouldn't record it and create a matching
resource.

This fixes a problem discovered by cluster discovery tests when node
establishes more than a single identity on initial boot with first one
being lost, but still exists in the discovery service.

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
  • Loading branch information
smira committed Oct 25, 2021
1 parent 0a964d9 commit 1d1e1df
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,12 @@ func (s *Server) Rollback(ctx context.Context, in *machine.RollbackRequest) (*ma
}

if err := func() error {
if err := mount.SystemPartitionMount(s.Controller.Runtime(), constants.BootPartitionLabel); err != nil {
if err := mount.SystemPartitionMount(s.Controller.Runtime(), nil, constants.BootPartitionLabel); err != nil {
return fmt.Errorf("error mounting boot partition: %w", err)
}

defer func() {
if err := mount.SystemPartitionUnmount(s.Controller.Runtime(), constants.BootPartitionLabel); err != nil {
if err := mount.SystemPartitionUnmount(s.Controller.Runtime(), nil, constants.BootPartitionLabel); err != nil {
log.Printf("failed unmounting boot partition: %s", err)
}
}()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1524,28 +1524,28 @@ func SaveStateEncryptionConfig(seq runtime.Sequence, data interface{}) (runtime.
// MountBootPartition mounts the boot partition.
func MountBootPartition(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
return mount.SystemPartitionMount(r, constants.BootPartitionLabel)
return mount.SystemPartitionMount(r, logger, constants.BootPartitionLabel)
}, "mountBootPartition"
}

// UnmountBootPartition unmounts the boot partition.
func UnmountBootPartition(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) error {
return mount.SystemPartitionUnmount(r, constants.BootPartitionLabel)
return mount.SystemPartitionUnmount(r, logger, constants.BootPartitionLabel)
}, "unmountBootPartition"
}

// MountEFIPartition mounts the EFI partition.
func MountEFIPartition(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
return mount.SystemPartitionMount(r, constants.EFIPartitionLabel)
return mount.SystemPartitionMount(r, logger, constants.EFIPartitionLabel)
}, "mountEFIPartition"
}

// UnmountEFIPartition unmounts the EFI partition.
func UnmountEFIPartition(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) error {
return mount.SystemPartitionUnmount(r, constants.EFIPartitionLabel)
return mount.SystemPartitionUnmount(r, logger, constants.EFIPartitionLabel)
}, "unmountEFIPartition"
}

Expand Down Expand Up @@ -1592,28 +1592,28 @@ func MountStatePartition(seq runtime.Sequence, data interface{}) (runtime.TaskEx
opts = append(opts, mount.WithEncryptionConfig(encryption))
}

return mount.SystemPartitionMount(r, constants.StatePartitionLabel, opts...)
return mount.SystemPartitionMount(r, logger, constants.StatePartitionLabel, opts...)
}, "mountStatePartition"
}

// UnmountStatePartition unmounts the system partition.
func UnmountStatePartition(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) error {
return mount.SystemPartitionUnmount(r, constants.StatePartitionLabel)
return mount.SystemPartitionUnmount(r, logger, constants.StatePartitionLabel)
}, "unmountStatePartition"
}

// MountEphemeralPartition mounts the ephemeral partition.
func MountEphemeralPartition(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) error {
return mount.SystemPartitionMount(r, constants.EphemeralPartitionLabel, mount.WithFlags(mount.Resize))
return mount.SystemPartitionMount(r, logger, constants.EphemeralPartitionLabel, mount.WithFlags(mount.Resize))
}, "mountEphemeralPartition"
}

// UnmountEphemeralPartition unmounts the ephemeral partition.
func UnmountEphemeralPartition(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
return mount.SystemPartitionUnmount(r, constants.EphemeralPartitionLabel)
return mount.SystemPartitionUnmount(r, logger, constants.EphemeralPartitionLabel)
}, "unmountEphemeralPartition"
}

Expand Down
16 changes: 7 additions & 9 deletions internal/pkg/mount/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func Mount(mountpoints *Points) (err error) {
// Mount the device(s).

for iter.Next() {
if err = mountMountpoint(iter.Value()); err != nil {
if _, err = mountMountpoint(iter.Value()); err != nil {
return fmt.Errorf("error mounting %q: %w", iter.Value().Source(), err)
}
}
Expand All @@ -46,20 +46,18 @@ func Mount(mountpoints *Points) (err error) {
}

//nolint:gocyclo
func mountMountpoint(mountpoint *Point) (err error) {
var skipMount bool

func mountMountpoint(mountpoint *Point) (skipMount bool, err error) {
// Repair the disk's partition table.
if mountpoint.MountFlags.Check(Resize) {
if _, err = mountpoint.ResizePartition(); err != nil {
return fmt.Errorf("error resizing %w", err)
return false, fmt.Errorf("error resizing %w", err)
}
}

if mountpoint.MountFlags.Check(SkipIfMounted) {
skipMount, err = mountpoint.IsMounted()
if err != nil {
return fmt.Errorf("mountpoint is set to skip if mounted, but the mount check failed: %w", err)
return false, fmt.Errorf("mountpoint is set to skip if mounted, but the mount check failed: %w", err)
}
}

Expand All @@ -69,7 +67,7 @@ func mountMountpoint(mountpoint *Point) (err error) {

if !skipMount {
if err = mountpoint.Mount(); err != nil {
return fmt.Errorf("error mounting: %w", err)
return false, fmt.Errorf("error mounting: %w", err)
}
}

Expand All @@ -79,11 +77,11 @@ func mountMountpoint(mountpoint *Point) (err error) {
// when partition was resized, but growfs never got called.
if mountpoint.MountFlags.Check(Resize) {
if err = mountpoint.GrowFilesystem(); err != nil {
return fmt.Errorf("error resizing filesystem: %w", err)
return false, fmt.Errorf("error resizing filesystem: %w", err)
}
}

return nil
return skipMount, nil
}

// Unmount unmounts the device(s).
Expand Down
23 changes: 20 additions & 3 deletions internal/pkg/mount/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package mount
import (
"context"
"fmt"
"log"
"os"
"sync"

Expand Down Expand Up @@ -178,7 +179,9 @@ func SystemMountPointForLabel(device *blockdevice.BlockDevice, label string, opt
}

// SystemPartitionMount mounts a system partition by the label.
func SystemPartitionMount(r runtime.Runtime, label string, opts ...Option) (err error) {
//
//nolint:gocyclo
func SystemPartitionMount(r runtime.Runtime, logger *log.Logger, label string, opts ...Option) (err error) {
device := r.State().Machine().Disk(disk.WithPartitionLabel(label))
if device == nil {
return fmt.Errorf("failed to find device with partition labeled %s", label)
Expand All @@ -203,10 +206,20 @@ func SystemPartitionMount(r runtime.Runtime, label string, opts ...Option) (err
return fmt.Errorf("no mountpoints for label %q", label)
}

if err = mountMountpoint(mountpoint); err != nil {
var skipMount bool

if skipMount, err = mountMountpoint(mountpoint); err != nil {
return err
}

if skipMount {
if logger != nil {
logger.Printf("mount skipped")
}

return
}

// record mount as the resource
mountStatus := runtimeres.NewMountStatus(v1alpha1.NamespaceName, label)
mountStatus.TypedSpec().Source = mountpoint.Source()
Expand All @@ -227,12 +240,16 @@ func SystemPartitionMount(r runtime.Runtime, label string, opts ...Option) (err
}

// SystemPartitionUnmount unmounts a system partition by the label.
func SystemPartitionUnmount(r runtime.Runtime, label string) (err error) {
func SystemPartitionUnmount(r runtime.Runtime, logger *log.Logger, label string) (err error) {
mountpointsMutex.RLock()
mountpoint, ok := mountpoints[label]
mountpointsMutex.RUnlock()

if !ok {
if logger != nil {
logger.Printf("unmount skipped")
}

return nil
}

Expand Down

0 comments on commit 1d1e1df

Please sign in to comment.