Skip to content

Commit

Permalink
feat: add an option to open block device with exclusive flock
Browse files Browse the repository at this point in the history
The problem is the interaction of udevd and our code managing partition
table: udevd might trigger `BLKRRPART` ioctl concurrently with our code
which tries to sync partition table which leads to a mess.

With `flock(LOCK_EX)` udevd skips `BLKRRPART` syscall.

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
  • Loading branch information
smira authored and talos-bot committed Jan 27, 2021
1 parent 5a1c7f7 commit b0375e4
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
8 changes: 8 additions & 0 deletions blockdevice/blockdevice_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ func Open(devname string, setters ...Option) (bd *BlockDevice, err error) {
}
}()

if opts.ExclusiveLock {
if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil {
err = fmt.Errorf("error locking device %q: %w", devname, err)

return nil, err
}
}

if opts.CreateGPT {
var g *gpt.GPT

Expand Down
10 changes: 9 additions & 1 deletion blockdevice/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ package blockdevice

// Options is the functional options struct.
type Options struct {
CreateGPT bool
CreateGPT bool
ExclusiveLock bool
}

// Option is the functional option func.
Expand All @@ -19,6 +20,13 @@ func WithNewGPT(o bool) Option {
}
}

// WithExclusiveLock locks the blockdevice for exclusive access using flock().
func WithExclusiveLock(o bool) Option {
return func(args *Options) {
args.ExclusiveLock = o
}
}

// NewDefaultOptions initializes a Options struct with default values.
func NewDefaultOptions(setters ...Option) *Options {
opts := &Options{
Expand Down

0 comments on commit b0375e4

Please sign in to comment.