Skip to content

Commit

Permalink
Add VirDomain.GetCPUStats and VirDomain.GetInterfaceParameters
Browse files Browse the repository at this point in the history
Remove integration tests as they will not work with this
version.

Replace virTypedParamsFree with manual C.free calls to alloc'ed
strings, since it is not available before libvirt 1.0.2.
  • Loading branch information
christopherobin authored and alexzorin committed May 10, 2014
1 parent 3796356 commit ddb5e4e
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 1 deletion.
99 changes: 99 additions & 0 deletions domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import "C"

import (
"errors"
"reflect"
"strings"
"unsafe"
)

Expand All @@ -21,6 +23,56 @@ type VirDomainInfo struct {
ptr C.virDomainInfo
}

type VirTypedParameter struct {
Name string
Value interface{}
}

type VirTypedParameters []VirTypedParameter

func (dest *VirTypedParameters) loadFromCPtr(params C.virTypedParameterPtr, nParams int) {
// reset slice
*dest = VirTypedParameters{}

// transform that C array to a go slice
hdr := reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(params)),
Len: int(nParams),
Cap: int(nParams),
}
rawParams := *(*[]C.struct__virTypedParameter)(unsafe.Pointer(&hdr))

// there is probably a more elegant way to deal with that union
for _, rawParam := range rawParams {
name := C.GoStringN(&rawParam.field[0], C.VIR_TYPED_PARAM_FIELD_LENGTH)
if nbIdx := strings.Index(name, "\x00"); nbIdx != -1 {
name = name[:nbIdx]
}
switch rawParam._type {
case C.VIR_TYPED_PARAM_INT:
*dest = append(*dest, VirTypedParameter{name, int(*(*C.int)(unsafe.Pointer(&rawParam.value[0])))})
case C.VIR_TYPED_PARAM_UINT:
*dest = append(*dest, VirTypedParameter{name, uint32(*(*C.uint)(unsafe.Pointer(&rawParam.value[0])))})
case C.VIR_TYPED_PARAM_LLONG:
*dest = append(*dest, VirTypedParameter{name, int64(*(*C.longlong)(unsafe.Pointer(&rawParam.value[0])))})
case C.VIR_TYPED_PARAM_ULLONG:
*dest = append(*dest, VirTypedParameter{name, uint64(*(*C.ulonglong)(unsafe.Pointer(&rawParam.value[0])))})
case C.VIR_TYPED_PARAM_DOUBLE:
*dest = append(*dest, VirTypedParameter{name, float64(*(*C.double)(unsafe.Pointer(&rawParam.value[0])))})
case C.VIR_TYPED_PARAM_BOOLEAN:
if int(*(*C.char)(unsafe.Pointer(&rawParam.value[0]))) == 1 {
*dest = append(*dest, VirTypedParameter{name, true})
} else {
*dest = append(*dest, VirTypedParameter{name, false})
}
case C.VIR_TYPED_PARAM_STRING:
ptr := (*C.char)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&rawParam.value[0]))))
*dest = append(*dest, VirTypedParameter{name, C.GoString(ptr)})
C.free(unsafe.Pointer(ptr))
}
}
}

func (d *VirDomain) Free() error {
if result := C.virDomainFree(d.ptr); result != 0 {
return errors.New(GetLastError())
Expand Down Expand Up @@ -182,6 +234,53 @@ func (i *VirDomainInfo) GetCpuTime() uint64 {
return uint64(i.ptr.cpuTime)
}

func (d *VirDomain) GetCPUStats(params *VirTypedParameters, nParams int, startCpu int, nCpus uint32, flags uint32) (int, error) {
var cParams C.virTypedParameterPtr
var cParamsLen int

cParamsLen = int(nCpus) * nParams

if params != nil && cParamsLen > 0 {
cParams = (C.virTypedParameterPtr)(C.calloc(C.size_t(cParamsLen), C.size_t(unsafe.Sizeof(C.struct__virTypedParameter{}))))
} else {
cParamsLen = 0
cParams = nil
}

result := int(C.virDomainGetCPUStats(d.ptr, (C.virTypedParameterPtr)(cParams), C.uint(nParams), C.int(startCpu), C.uint(nCpus), C.uint(flags)))
if result == -1 {
return result, errors.New(GetLastError())
}

if cParamsLen > 0 {
params.loadFromCPtr(cParams, cParamsLen)
}

return result, nil
}

// Warning: No test written for this function
func (d *VirDomain) GetInterfaceParameters(device string, params *VirTypedParameters, nParams *int, flags uint32) (int, error) {
var cParams C.virTypedParameterPtr

if params != nil && *nParams > 0 {
cParams = (C.virTypedParameterPtr)(C.calloc(C.size_t(*nParams), C.size_t(unsafe.Sizeof(C.struct__virTypedParameter{}))))
} else {
cParams = nil
}

result := int(C.virDomainGetInterfaceParameters(d.ptr, C.CString(device), (C.virTypedParameterPtr)(cParams), (*C.int)(unsafe.Pointer(nParams)), C.uint(flags)))
if result == -1 {
return result, errors.New(GetLastError())
}

if params != nil && *nParams > 0 {
params.loadFromCPtr(cParams, *nParams)
}

return result, nil
}

func (d *VirDomain) Undefine() error {
result := C.virDomainUndefine(d.ptr)
if result == -1 {
Expand Down
1 change: 0 additions & 1 deletion integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,4 +536,3 @@ func TestIntegrationLookupSecretByUsage(t *testing.T) {
t.Fatal(err)
}
}

0 comments on commit ddb5e4e

Please sign in to comment.