mounter_freebsd.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package mount
  2. /*
  3. #include <errno.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/_iovec.h>
  7. #include <sys/mount.h>
  8. #include <sys/param.h>
  9. */
  10. import "C"
  11. import (
  12. "fmt"
  13. "strings"
  14. "syscall"
  15. "unsafe"
  16. )
  17. func allocateIOVecs(options []string) []C.struct_iovec {
  18. out := make([]C.struct_iovec, len(options))
  19. for i, option := range options {
  20. out[i].iov_base = unsafe.Pointer(C.CString(option))
  21. out[i].iov_len = C.size_t(len(option) + 1)
  22. }
  23. return out
  24. }
  25. func mount(device, target, mType string, flag uintptr, data string) error {
  26. isNullFS := false
  27. xs := strings.Split(data, ",")
  28. for _, x := range xs {
  29. if x == "bind" {
  30. isNullFS = true
  31. }
  32. }
  33. options := []string{"fspath", target}
  34. if isNullFS {
  35. options = append(options, "fstype", "nullfs", "target", device)
  36. } else {
  37. options = append(options, "fstype", mType, "from", device)
  38. }
  39. rawOptions := allocateIOVecs(options)
  40. for _, rawOption := range rawOptions {
  41. defer C.free(rawOption.iov_base)
  42. }
  43. if errno := C.nmount(&rawOptions[0], C.uint(len(options)), C.int(flag)); errno != 0 {
  44. reason := C.GoString(C.strerror(*C.__error()))
  45. return fmt.Errorf("Failed to call nmount: %s", reason)
  46. }
  47. return nil
  48. }
  49. func unmount(target string, flag int) error {
  50. return syscall.Unmount(target, flag)
  51. }