func safeThing(t reflect.Type) bool {
	switch t.Kind() {
	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return true
	case reflect.Array:
		return safeThing(t.Elem())
	case reflect.Struct:
		for i := 0; i < t.NumField(); i++ {
			if !safeThing(t.Field(i).Type) {
				return false
			}
		}
		return true
	default:
		return false
	}
}
Support for copying semi-arbitrary structures out of raw
KStats.

safeThing returns true if a given type is either a simple defined
size primitive integer type or an array and/or struct composed
entirely of safe things. A safe thing is entirely self contained
and may be initialized from random memory without breaking Go's
memory safety (although the values it contains may be garbage).
package kstat
import "C"
import (
	"errors"
	"fmt"
	"reflect"
	"unsafe"
)
type Raw struct {
	Data     []byte
	Ndata    uint64
	Snaptime int64
	KStat    *KStat
}
func (k *KStat) prep() error {
	if k.invalid() {
		return errors.New("invalid KStat or closed token")
	}
	if k.ksp.ks_data == nil {
		if err := k.Refresh(); err != nil {
			return err
		}
	}
	return nil
}
func (k *KStat) Raw() (*Raw, error) {
	if err := k.prep(); err != nil {
		return nil, err
	}
	r := Raw{}
	r.KStat = k
	r.Snaptime = k.Snaptime
	r.Ndata = uint64(k.ksp.ks_ndata)
	r.Data = C.GoBytes(unsafe.Pointer(k.ksp.ks_data), C.int(k.ksp.ks_data_size))
	return &r, nil
}
func (tok *Token) prepunix(name string, size uintptr) (*KStat, error) {
	k, err := tok.Lookup("unix", 0, name)
	if err != nil {
		return nil, err
	}
	if k.ksp.ks_type != C.KSTAT_TYPE_RAW {
		return nil, fmt.Errorf("%s is wrong type %s", k, k.Type)
	}
	if uintptr(k.ksp.ks_data_size) != size {
		return nil, fmt.Errorf("%s is wrong size %d (should be %d)", k, k.ksp.ks_data_size, size)
	}
	return k, nil
}
func (tok *Token) Sysinfo() (*KStat, *Sysinfo, error) {
	var si Sysinfo
	k, err := tok.prepunix("sysinfo", unsafe.Sizeof(si))
	if err != nil {
		return nil, nil, err
	}
	si = *((*Sysinfo)(k.ksp.ks_data))
	return k, &si, nil
}
func (tok *Token) Vminfo() (*KStat, *Vminfo, error) {
	var vi Vminfo
	k, err := tok.prepunix("vminfo", unsafe.Sizeof(vi))
	if err != nil {
		return nil, nil, err
	}
	vi = *((*Vminfo)(k.ksp.ks_data))
	return k, &vi, nil
}
func (tok *Token) Var() (*KStat, *Var, error) {
	var vi Var
	k, err := tok.prepunix("var", unsafe.Sizeof(vi))
	if err != nil {
		return nil, nil, err
	}
	vi = *((*Var)(k.ksp.ks_data))
	return k, &vi, nil
}
func (k *KStat) GetMntinfo() (*Mntinfo, error) {
	var mi Mntinfo
	if err := k.prep(); err != nil {
		return nil, err
	}
	if k.Type != RawStat || k.Module != "nfs" || k.Name != "mntinfo" {
		return nil, errors.New("KStat is not a Mntinfo kstat")
	}
	if uintptr(k.ksp.ks_data_size) != unsafe.Sizeof(mi) {
		return nil, fmt.Errorf("KStat is wrong size %d (should be %d)", k.ksp.ks_data_size, unsafe.Sizeof(mi))
	}
	mi = *((*Mntinfo)(k.ksp.ks_data))
	return &mi, nil
}