Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mountinfo: BSDs no longer need cgo nor reflect #114

Merged
merged 1 commit into from May 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions mountinfo/mounted_unix.go
@@ -1,5 +1,5 @@
//go:build linux || (freebsd && cgo) || (openbsd && cgo) || (darwin && cgo)
// +build linux freebsd,cgo openbsd,cgo darwin,cgo
//go:build linux || freebsd || openbsd || darwin
// +build linux freebsd openbsd darwin

package mountinfo

Expand Down
44 changes: 14 additions & 30 deletions mountinfo/mountinfo_bsd.go
@@ -1,53 +1,37 @@
//go:build (freebsd && cgo) || (openbsd && cgo) || (darwin && cgo)
// +build freebsd,cgo openbsd,cgo darwin,cgo
//go:build freebsd || openbsd || darwin
// +build freebsd openbsd darwin

package mountinfo

/*
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
*/
import "C"

import (
"fmt"
"reflect"
"unsafe"
)
import "golang.org/x/sys/unix"

// parseMountTable returns information about mounted filesystems
func parseMountTable(filter FilterFunc) ([]*Info, error) {
var rawEntries *C.struct_statfs

count := int(C.getmntinfo(&rawEntries, C.MNT_WAIT))
if count == 0 {
return nil, fmt.Errorf("failed to call getmntinfo")
count, err := unix.Getfsstat(nil, unix.MNT_WAIT)
if err != nil {
return nil, err
}

var entries []C.struct_statfs
header := (*reflect.SliceHeader)(unsafe.Pointer(&entries))
header.Cap = count
header.Len = count
header.Data = uintptr(unsafe.Pointer(rawEntries))
entries := make([]unix.Statfs_t, count)
_, err = unix.Getfsstat(entries, unix.MNT_WAIT)
if err != nil {
return nil, err
}

var out []*Info
for _, entry := range entries {
var mountinfo Info
var skip, stop bool
mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0])
mountinfo.FSType = C.GoString(&entry.f_fstypename[0])
mountinfo.Source = C.GoString(&entry.f_mntfromname[0])
mountinfo := getMountinfo(&entry)

if filter != nil {
// filter out entries we're not interested in
skip, stop = filter(&mountinfo)
skip, stop = filter(mountinfo)
if skip {
continue
}
}

out = append(out, &mountinfo)
out = append(out, mountinfo)
if stop {
break
}
Expand Down
14 changes: 14 additions & 0 deletions mountinfo/mountinfo_freebsdlike.go
@@ -0,0 +1,14 @@
//go:build freebsd || darwin
// +build freebsd darwin

package mountinfo

import "golang.org/x/sys/unix"

func getMountinfo(entry *unix.Statfs_t) *Info {
var mountinfo Info
mountinfo.Mountpoint = unix.ByteSliceToString(entry.Mntonname[:])
mountinfo.FSType = unix.ByteSliceToString(entry.Fstypename[:])
mountinfo.Source = unix.ByteSliceToString(entry.Mntfromname[:])
return &mountinfo
}
22 changes: 22 additions & 0 deletions mountinfo/mountinfo_openbsd.go
@@ -0,0 +1,22 @@
package mountinfo

import "golang.org/x/sys/unix"

func int8SliceToString(is []int8) string {
var bs []byte
for _, i := range is {
if i == 0 {
break
}
bs = append(bs, byte(i))
}
return string(bs)
Comment on lines +6 to +13
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I overlooked it. This function is probably doing some excessive allocations and copying and should be rewritten

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can not think of a better way without unsafe. If you are sure, then I will rewrite it with unsafe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrited with unsafe.
#117

}

func getMountinfo(entry *unix.Statfs_t) *Info {
var mountinfo Info
mountinfo.Mountpoint = int8SliceToString(entry.F_mntonname[:])
mountinfo.FSType = int8SliceToString(entry.F_fstypename[:])
mountinfo.Source = int8SliceToString(entry.F_mntfromname[:])
Comment on lines +18 to +20
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you forgot to switch to unix.ByteSliceToString here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, weird.

This is probably something that needs to be fixed in x/sys/unix. Something similar to e.g. https://go-review.googlesource.com/c/sys/+/359674 needs to be done.

If you have openbsd running, you can prepare a patch to x/sys/unix similar to the above; if not, I can try to do that or we can maybe kindly ask @tklauser

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I will make a patch to x/sys/unix for OpenBSD.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return &mountinfo
}
4 changes: 2 additions & 2 deletions mountinfo/mountinfo_unsupported.go
@@ -1,5 +1,5 @@
//go:build (!windows && !linux && !freebsd && !openbsd && !darwin) || (freebsd && !cgo) || (openbsd && !cgo) || (darwin && !cgo)
// +build !windows,!linux,!freebsd,!openbsd,!darwin freebsd,!cgo openbsd,!cgo darwin,!cgo
//go:build !windows && !linux && !freebsd && !openbsd && !darwin
// +build !windows,!linux,!freebsd,!openbsd,!darwin

package mountinfo

Expand Down