aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/errors.go4
-rw-r--r--util/util.go48
-rw-r--r--util/util_test.go7
3 files changed, 50 insertions, 9 deletions
diff --git a/util/errors.go b/util/errors.go
index f10569e..3c87a2c 100644
--- a/util/errors.go
+++ b/util/errors.go
@@ -72,7 +72,7 @@ type ErrWriter struct {
err error
}
-// NewErrWriter creates an ErrWriter which wraps the provided reader.
+// NewErrWriter creates an ErrWriter which wraps the provided writer.
func NewErrWriter(writer io.Writer) *ErrWriter {
return &ErrWriter{w: writer, err: nil}
}
@@ -116,7 +116,7 @@ func NeverError(err error) {
}
var (
- // testEnvVarName is the name on an environment variable that should be
+ // testEnvVarName is the name of an environment variable that should be
// set to an empty mountpoint. This is only used for integration tests.
// If not set, integration tests are skipped.
testEnvVarName = "TEST_FILESYSTEM_ROOT"
diff --git a/util/util.go b/util/util.go
index 3de4a1a..1dab335 100644
--- a/util/util.go
+++ b/util/util.go
@@ -25,14 +25,17 @@ package util
import (
"bufio"
- "math"
+ "fmt"
+ "log"
"os"
"os/user"
"strconv"
"unsafe"
+
+ "golang.org/x/sys/unix"
)
-// Ptr converts an Go byte array to a pointer to the start of the array.
+// Ptr converts a Go byte array to a pointer to the start of the array.
func Ptr(slice []byte) unsafe.Pointer {
if len(slice) == 0 {
return nil
@@ -43,15 +46,15 @@ func Ptr(slice []byte) unsafe.Pointer {
// ByteSlice takes a pointer to some data and views it as a slice of bytes.
// Note, indexing into this slice is unsafe.
func ByteSlice(ptr unsafe.Pointer) []byte {
- // Silce must fix in 32-bit address space to build on 32-bit platforms.
- return (*[math.MaxInt32]byte)(ptr)[:]
+ // Slice must fit in the smallest address space go supports.
+ return (*[1 << 30]byte)(ptr)[:]
}
// PointerSlice takes a pointer to an array of pointers and views it as a slice
// of pointers. Note, indexing into this slice is unsafe.
func PointerSlice(ptr unsafe.Pointer) []unsafe.Pointer {
- // Silce must fix in 32-bit address space to build on 32-bit platforms.
- return (*[math.MaxInt32 / 4]unsafe.Pointer)(ptr)[:]
+ // Slice must fit in the smallest address space go supports.
+ return (*[1 << 28]unsafe.Pointer)(ptr)[:]
}
// Index returns the first index i such that inVal == inArray[i].
@@ -118,12 +121,43 @@ func AtoiOrPanic(input string) int {
return i
}
+// UserFromUID returns the User corresponding to the given user id.
+func UserFromUID(uid int64) (*user.User, error) {
+ return user.LookupId(strconv.FormatInt(uid, 10))
+}
+
// EffectiveUser returns the user entry corresponding to the effective user.
func EffectiveUser() (*user.User, error) {
- return user.LookupId(strconv.Itoa(os.Geteuid()))
+ return UserFromUID(int64(os.Geteuid()))
}
// IsUserRoot checks if the effective user is root.
func IsUserRoot() bool {
return os.Geteuid() == 0
}
+
+// Chown changes the owner of a File to a User.
+func Chown(file *os.File, user *user.User) error {
+ uid := AtoiOrPanic(user.Uid)
+ gid := AtoiOrPanic(user.Gid)
+ return file.Chown(uid, gid)
+}
+
+// IsKernelVersionAtLeast returns true if the Linux kernel version is at least
+// major.minor. If something goes wrong it assumes false.
+func IsKernelVersionAtLeast(major, minor int) bool {
+ var uname unix.Utsname
+ if err := unix.Uname(&uname); err != nil {
+ log.Printf("Uname failed [%v], assuming old kernel", err)
+ return false
+ }
+ release := string(uname.Release[:])
+ log.Printf("Kernel version is %s", release)
+ var actualMajor, actualMinor int
+ if n, _ := fmt.Sscanf(release, "%d.%d", &actualMajor, &actualMinor); n != 2 {
+ log.Printf("Unrecognized uname format %q, assuming old kernel", release)
+ return false
+ }
+ return actualMajor > major ||
+ (actualMajor == major && actualMinor >= minor)
+}
diff --git a/util/util_test.go b/util/util_test.go
index 7739edd..70e7070 100644
--- a/util/util_test.go
+++ b/util/util_test.go
@@ -91,3 +91,10 @@ func TestNeverErrorNoPanic(t *testing.T) {
NeverError(nil)
}
+
+func TestIsKernelVersionAtLeast(t *testing.T) {
+ // Even just running Go requires at least v2.6.23, so...
+ if !IsKernelVersionAtLeast(2, 6) {
+ t.Error("IsKernelVersionAtLeast() is broken")
+ }
+}