o/blockdev: add options support

Allow passing options to Open(). This resolves a TODO left from when
blockdev was initially implemented and is now needed as Linux 6.12
rejects opening mounted block devices read-write, so we needed at least
a read-only option.

I also implemented the two options mentioned in the now-removed TODO
even though we're not using them yet.

These options are implemented generically to facilitate their use in
cross-platform code. Unsupported options are rejected at runtime. This
is similar to how Go's own stdlib does this.

Change-Id: I2548cb31e59a5c1198ca04537450bdf665878ca8
Reviewed-on: https://review.monogon.dev/c/monogon/+/3985
Reviewed-by: Jan Schär <jan@monogon.tech>
Tested-by: Jenkins CI
diff --git a/osbase/blockdev/blockdev_darwin.go b/osbase/blockdev/blockdev_darwin.go
index 46fa1ce..c40e8c3 100644
--- a/osbase/blockdev/blockdev_darwin.go
+++ b/osbase/blockdev/blockdev_darwin.go
@@ -69,8 +69,18 @@
 }
 
 // Open opens a block device given a path to its inode.
-func Open(path string) (*Device, error) {
-	outFile, err := os.OpenFile(path, os.O_RDWR, 0640)
+func Open(path string, opts ...Option) (*Device, error) {
+	var o options
+	o.collect(opts)
+	flags := o.genericFlags()
+	if o.direct {
+		return nil, errors.New("WithDirect not supported on macOS")
+	}
+	if o.exclusive {
+		return nil, errors.New("WithExclusive not supported on macOS")
+	}
+
+	outFile, err := os.OpenFile(path, flags, 0640)
 	if err != nil {
 		return nil, fmt.Errorf("failed to open block device: %w", err)
 	}