From 92a274e9a0a83b3e240784bf12817f08559ac8e8 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 24 May 2024 20:20:23 +0400 Subject: [PATCH] fix: workaround problems with udevd races When `udevd` rescans block device partitions while Talos is doing partitions, it might be that Talos can hit the following error while trying to open/mount a partition: ``` no such device or address ``` Previous attempts to fix that were using `ENODEV`, while the proper code is `ENXIO`. Also take exclusive lock while working with user disks to prevent concurrent udevd rescan. Signed-off-by: Andrey Smirnov --- cmd/installer/pkg/install/install.go | 2 +- .../machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go | 4 ++-- internal/pkg/mount/mount.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/installer/pkg/install/install.go b/cmd/installer/pkg/install/install.go index d8bffaceb6..9fa203f356 100644 --- a/cmd/installer/pkg/install/install.go +++ b/cmd/installer/pkg/install/install.go @@ -445,7 +445,7 @@ func retryBlockdeviceOpen(device string) (*blockdevice.BlockDevice, error) { switch { case os.IsNotExist(openErr): return retry.ExpectedError(openErr) - case errors.Is(openErr, syscall.ENODEV): + case errors.Is(openErr, syscall.ENODEV), errors.Is(openErr, syscall.ENXIO): return retry.ExpectedError(openErr) default: return nil 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 cb28018ed4..dfca4b921a 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go @@ -850,7 +850,7 @@ func partitionAndFormatDisks(logger *log.Logger, r runtime.Runtime) error { for _, disk := range r.Config().Machine().Disks() { if err := func() error { - bd, err := blockdevice.Open(disk.Device(), blockdevice.WithMode(blockdevice.ReadonlyMode)) + bd, err := blockdevice.Open(disk.Device(), blockdevice.WithMode(blockdevice.ReadonlyMode), blockdevice.WithExclusiveLock(true)) if err != nil { return err } @@ -921,7 +921,7 @@ func mountDisks(logger *log.Logger, r runtime.Runtime) (err error) { mountpoints := mount.NewMountPoints() for _, disk := range r.Config().Machine().Disks() { - bd, err := blockdevice.Open(disk.Device(), blockdevice.WithMode(blockdevice.ReadonlyMode)) + bd, err := blockdevice.Open(disk.Device(), blockdevice.WithMode(blockdevice.ReadonlyMode), blockdevice.WithExclusiveLock(true)) if err != nil { return err } diff --git a/internal/pkg/mount/mount.go b/internal/pkg/mount/mount.go index 08c0be8946..79a83ed36f 100644 --- a/internal/pkg/mount/mount.go +++ b/internal/pkg/mount/mount.go @@ -148,7 +148,7 @@ func mountRetry(f RetryFunc, p *Point, isUnmount bool) (err error) { switch err { case unix.EBUSY: return retry.ExpectedError(err) - case unix.ENOENT, unix.ENODEV: + case unix.ENOENT, unix.ENXIO: // if udevd triggers BLKRRPART ioctl, partition device entry might disappear temporarily return retry.ExpectedError(err) case unix.EUCLEAN, unix.EIO: