From eff8446072ad8dd1d6582a3d22a1758696f38511 Mon Sep 17 00:00:00 2001 From: Muhammad Kaisar Arkhan Date: Fri, 18 Dec 2020 20:36:27 +0100 Subject: [PATCH] Create proper mounter for OpenBSD OpenBSD's mount(2) works differently since it uses separate structs to present options for different filesystems, unlike in FreeBSD. It also means that support for other filesystems need to be added explicitly. I'm not sure which ones are required for now so I just write support for only FFS, which is the go-to filesystem used by OpenBSD systems. Signed-off-by: Muhammad Kaisar Arkhan --- mount/{mounter_bsd.go => mounter_freebsd.go} | 2 +- mount/mounter_openbsd.go | 77 ++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) rename mount/{mounter_bsd.go => mounter_freebsd.go} (97%) create mode 100644 mount/mounter_openbsd.go diff --git a/mount/mounter_bsd.go b/mount/mounter_freebsd.go similarity index 97% rename from mount/mounter_bsd.go rename to mount/mounter_freebsd.go index 656b762f..9b2d26c4 100644 --- a/mount/mounter_bsd.go +++ b/mount/mounter_freebsd.go @@ -1,4 +1,4 @@ -// +build freebsd,cgo openbsd,cgo +// +build freebsd,cgo package mount diff --git a/mount/mounter_openbsd.go b/mount/mounter_openbsd.go new file mode 100644 index 00000000..28cddf16 --- /dev/null +++ b/mount/mounter_openbsd.go @@ -0,0 +1,77 @@ +// +build openbsd,cgo + +/* + Due to how OpenBSD mount(2) works, filesystem types need to be + supported explicitly since it uses separate structs to pass + filesystem-specific arguments. + + For now only UFS/FFS is supported as it's the default fs + on OpenBSD systems. + + See: https://man.openbsd.org/mount.2 +*/ + +package mount + +/* +#include +#include +*/ +import "C" + +import ( + "fmt" + "syscall" + "unsafe" +) + +func createExportInfo(readOnly bool) C.struct_export_args { + exportFlags := C.int(0) + if readOnly { + exportFlags = C.MNT_EXRDONLY + } + out := C.struct_export_args{ + ex_root: 0, + ex_flags: exportFlags, + } + return out +} + +func createUfsArgs(device string, readOnly bool) unsafe.Pointer { + out := &C.struct_ufs_args{ + fspec: C.CString(device), + export_info: createExportInfo(readOnly), + } + return unsafe.Pointer(out) +} + +func mount(device, target, mType string, flag uintptr, data string) error { + readOnly := flag&RDONLY != 0 + + var fsArgs unsafe.Pointer + + switch mType { + case "ffs": + fsArgs = createUfsArgs(device, readOnly) + default: + return &mountError{ + op: "mount", + source: device, + target: target, + flags: flag, + err: fmt.Errorf("unsupported file system type: %s", mType), + } + } + + if errno := C.mount(C.CString(mType), C.CString(target), C.int(flag), fsArgs); errno != 0 { + return &mountError{ + op: "mount", + source: device, + target: target, + flags: flag, + err: syscall.Errno(errno), + } + } + + return nil +}