Add Get/SetBlockIoTune to go-libvirt API. (#45)
* Add Get/SetBlockIoTune to go-libvirt API. This adds two libvirt entry points to the go-libvirt API: virDomainSetBlockIoTune and virDomainGetBlockIoTune. These can be used to control block device throttling for a VM.
This commit is contained in:
parent
85dc33f30e
commit
c8e4b6a7b8
@ -53,6 +53,8 @@ const (
|
|||||||
ProcDomainUndefineFlags = 231
|
ProcDomainUndefineFlags = 231
|
||||||
ProcDomainDestroyFlags = 234
|
ProcDomainDestroyFlags = 234
|
||||||
ProcDomainReset = 245
|
ProcDomainReset = 245
|
||||||
|
ProcDomainSetBlockIOTune = 252
|
||||||
|
ProcDomainGetBlockIOTune = 253
|
||||||
ProcDomainShutdownFlags = 258
|
ProcDomainShutdownFlags = 258
|
||||||
ProcConnectListAllDomains = 273
|
ProcConnectListAllDomains = 273
|
||||||
ProcConnectListAllStoragePools = 281
|
ProcConnectListAllStoragePools = 281
|
||||||
@ -78,4 +80,8 @@ const (
|
|||||||
|
|
||||||
// UUIDSize is the length of a UUID, in bytes.
|
// UUIDSize is the length of a UUID, in bytes.
|
||||||
UUIDSize = 16
|
UUIDSize = 16
|
||||||
|
|
||||||
|
// TypedParamFieldLength is VIR_TYPED_PARAM_FIELD_LENGTH, and is the maximum
|
||||||
|
// length of the Field string in virTypedParameter structs.
|
||||||
|
TypedParamFieldLength = 80
|
||||||
)
|
)
|
||||||
|
225
libvirt.go
225
libvirt.go
@ -19,6 +19,7 @@ package libvirt
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -94,6 +95,86 @@ type qemuError struct {
|
|||||||
// DomainXMLFlags specifies options for dumping a domain's XML.
|
// DomainXMLFlags specifies options for dumping a domain's XML.
|
||||||
type DomainXMLFlags uint32
|
type DomainXMLFlags uint32
|
||||||
|
|
||||||
|
// DomainAffectFlags specifies options for whether an operation affects the
|
||||||
|
// running VM, or the persistent VM configuration on disk. See FlagDomain...
|
||||||
|
// consts for values.
|
||||||
|
type DomainAffectFlags uint32
|
||||||
|
|
||||||
|
// Consts used for flags
|
||||||
|
|
||||||
|
// virDomainModificationImpact and virTypedParameterFlags values. These are
|
||||||
|
// combined here because they are both used to set the same flags fields in the
|
||||||
|
// libvirt API.
|
||||||
|
const (
|
||||||
|
// FlagDomainAffectCurrent means affect the current domain state
|
||||||
|
FlagDomainAffectCurrent DomainAffectFlags = 0
|
||||||
|
// FlagDomainAffectLive means affect the running domain state
|
||||||
|
FlagDomainAffectLive = 1 << (iota - 1)
|
||||||
|
// FlagDomainAffectConfig means affect the persistent domain state.
|
||||||
|
FlagDomainAffectConfig
|
||||||
|
// FlagTypedParamStringOkay tells the server that this client understands
|
||||||
|
// TypedParameStrings.
|
||||||
|
FlagTypedParamStringOkay
|
||||||
|
)
|
||||||
|
|
||||||
|
// Consts relating to TypedParams:
|
||||||
|
const (
|
||||||
|
// TypedParamInt is a C int.
|
||||||
|
TypedParamInt = iota + 1
|
||||||
|
// TypedParamUInt is a C unsigned int.
|
||||||
|
TypedParamUInt
|
||||||
|
// TypedParamLLong is a C long long int.
|
||||||
|
TypedParamLLong
|
||||||
|
// TypedParamULLong is a C unsigned long long int.
|
||||||
|
TypedParamULLong
|
||||||
|
// TypedParamDouble is a C double.
|
||||||
|
TypedParamDouble
|
||||||
|
// TypedParamBoolean is a C char.
|
||||||
|
TypedParamBoolean
|
||||||
|
// TypedParamString is a C char*.
|
||||||
|
TypedParamString
|
||||||
|
|
||||||
|
// TypedParamLast is just an end-of-enum marker.
|
||||||
|
TypedParamLast
|
||||||
|
)
|
||||||
|
|
||||||
|
// TypedParam represents libvirt's virTypedParameter, which is used to pass
|
||||||
|
// typed parameters to libvirt functions. The `Value` field defined as a union
|
||||||
|
// in libvirt, and given the current set of types inside it, is 8 bytes long.
|
||||||
|
type TypedParam struct {
|
||||||
|
Field string
|
||||||
|
Type int
|
||||||
|
Value [8]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTypedParamInt returns a TypedParam encoding for an int.
|
||||||
|
func NewTypedParamInt(name string, v int) *TypedParam {
|
||||||
|
// Truncate the field name if it's longer than the limit.
|
||||||
|
if len(name) > constants.TypedParamFieldLength {
|
||||||
|
name = name[:constants.TypedParamFieldLength]
|
||||||
|
}
|
||||||
|
tp := TypedParam{
|
||||||
|
Field: name,
|
||||||
|
Type: TypedParamInt,
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint32(tp.Value[:], uint32(v))
|
||||||
|
return &tp
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTypedParamULongLong returns a TypedParam encoding for an unsigned long long.
|
||||||
|
func NewTypedParamULongLong(name string, v uint64) *TypedParam {
|
||||||
|
// Truncate the field name if it's longer than the limit.
|
||||||
|
if len(name) > constants.TypedParamFieldLength {
|
||||||
|
name = name[:constants.TypedParamFieldLength]
|
||||||
|
}
|
||||||
|
tp := TypedParam{
|
||||||
|
Field: name,
|
||||||
|
Type: TypedParamULLong,
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint64(tp.Value[:], v)
|
||||||
|
return &tp
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DomainXMLFlagSecure dumps XML with sensitive information included.
|
// DomainXMLFlagSecure dumps XML with sensitive information included.
|
||||||
DomainXMLFlagSecure DomainXMLFlags = 1 << iota
|
DomainXMLFlagSecure DomainXMLFlags = 1 << iota
|
||||||
@ -601,7 +682,7 @@ func (l *Libvirt) Events(dom string) (<-chan DomainEvent, error) {
|
|||||||
|
|
||||||
res := <-resp
|
res := <-resp
|
||||||
if res.Status != StatusOK {
|
if res.Status != StatusOK {
|
||||||
err := decodeError(res.Payload)
|
err = decodeError(res.Payload)
|
||||||
if err == ErrUnsupported {
|
if err == ErrUnsupported {
|
||||||
return nil, ErrEventsNotSupported
|
return nil, ErrEventsNotSupported
|
||||||
}
|
}
|
||||||
@ -1199,6 +1280,148 @@ func (l *Libvirt) Reset(dom string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BlockLimit contains a name and value pair for a Get/SetBlockIOTune limit. The
|
||||||
|
// Name field is the name of the limit (to see a list of the limits that can be
|
||||||
|
// applied, execute the 'blkdeviotune' command on a VM in virsh). Callers can
|
||||||
|
// use the QEMUBlockIO... constants below for the Name value. The Value field is
|
||||||
|
// the limit to apply.
|
||||||
|
type BlockLimit struct {
|
||||||
|
Name string
|
||||||
|
Value uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockIOTune-able values. These tunables are different for different
|
||||||
|
// hypervisors; currently only the tunables for QEMU are defined here. These are
|
||||||
|
// not necessarily the only possible values; different libvirt versions may add
|
||||||
|
// or remove parameters from this list.
|
||||||
|
const (
|
||||||
|
QEMUBlockIOTotalBytesSec = "total_bytes_sec"
|
||||||
|
QEMUBlockIOReadBytesSec = "read_bytes_sec"
|
||||||
|
QEMUBlockIOWriteBytesSec = "write_bytes_sec"
|
||||||
|
QEMUBlockIOTotalIOPSSec = "total_iops_sec"
|
||||||
|
QEMUBlockIOReadIOPSSec = "read_iops_sec"
|
||||||
|
QEMUBlockIOWriteIOPSSec = "write_iops_sec"
|
||||||
|
QEMUBlockIOTotalBytesSecMax = "total_bytes_sec_max"
|
||||||
|
QEMUBlockIOReadBytesSecMax = "read_bytes_sec_max"
|
||||||
|
QEMUBlockIOWriteBytesSecMax = "write_bytes_sec_max"
|
||||||
|
QEMUBlockIOTotalIOPSSecMax = "total_iops_sec_max"
|
||||||
|
QEMUBlockIOReadIOPSSecMax = "read_iops_sec_max"
|
||||||
|
QEMUBlockIOWriteIOPSSecMax = "write_iops_sec_max"
|
||||||
|
QEMUBlockIOSizeIOPSSec = "size_iops_sec"
|
||||||
|
QEMUBlockIOTotalBytesSecMaxLength = "total_bytes_sec_max_length"
|
||||||
|
QEMUBlockIOReadBytesSecMaxLength = "read_bytes_sec_max_length"
|
||||||
|
QEMUBlockIOWriteBytesSecMaxLength = "write_bytes_sec_max_length"
|
||||||
|
QEMUBlockIOTotalIOPSSecMaxLength = "total_iops_sec_max_length"
|
||||||
|
QEMUBlockIOReadIOPSSecMaxLength = "read_iops_sec_max_length"
|
||||||
|
QEMUBlockIOWriteIOPSSecMaxLength = "write_iops_sec_max_length"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetBlockIOTune changes the per-device block I/O tunables within a guest.
|
||||||
|
// Parameters are the name of the VM, the name of the disk device to which the
|
||||||
|
// limits should be applied, and 1 or more BlockLimit structs containing the
|
||||||
|
// actual limits.
|
||||||
|
//
|
||||||
|
// The limits which can be applied here are enumerated in the QEMUBlockIO...
|
||||||
|
// constants above, and you can also see the full list by executing the
|
||||||
|
// 'blkdeviotune' command on a VM in virsh.
|
||||||
|
//
|
||||||
|
// Example usage:
|
||||||
|
// SetBlockIOTune("vm-name", "vda", BlockLimit{libvirt.QEMUBlockIOWriteBytesSec, 1000000})
|
||||||
|
func (l *Libvirt) SetBlockIOTune(dom string, disk string, limits ...BlockLimit) error {
|
||||||
|
d, err := l.lookup(dom)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainSetBlockIoTune
|
||||||
|
payload := struct {
|
||||||
|
Domain Domain
|
||||||
|
Disk string
|
||||||
|
Params []TypedParam
|
||||||
|
Flags DomainAffectFlags
|
||||||
|
}{
|
||||||
|
Domain: *d,
|
||||||
|
Disk: disk,
|
||||||
|
Flags: FlagDomainAffectLive,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, limit := range limits {
|
||||||
|
tp := NewTypedParamULongLong(limit.Name, limit.Value)
|
||||||
|
payload.Params = append(payload.Params, *tp)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := encode(&payload)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := l.request(constants.ProcDomainSetBlockIOTune, constants.ProgramRemote, &buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := <-resp
|
||||||
|
if r.Status != StatusOK {
|
||||||
|
return decodeError(r.Payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlockIOTune returns a slice containing the current block I/O tunables for
|
||||||
|
// a disk.
|
||||||
|
func (l *Libvirt) GetBlockIOTune(dom string, disk string) ([]BlockLimit, error) {
|
||||||
|
d, err := l.lookup(dom)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := struct {
|
||||||
|
Domain Domain
|
||||||
|
Disk []string
|
||||||
|
ParamCount uint32
|
||||||
|
Flags DomainAffectFlags
|
||||||
|
}{
|
||||||
|
Domain: *d,
|
||||||
|
Disk: []string{disk},
|
||||||
|
ParamCount: 32,
|
||||||
|
Flags: FlagTypedParamStringOkay,
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := encode(&payload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := l.request(constants.ProcDomainGetBlockIOTune, constants.ProgramRemote, &buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := <-resp
|
||||||
|
if r.Status != StatusOK {
|
||||||
|
return nil, decodeError(r.Payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
dec := xdr.NewDecoder(bytes.NewReader(r.Payload))
|
||||||
|
result := struct {
|
||||||
|
Limits []TypedParam
|
||||||
|
ParamCount uint32
|
||||||
|
}{}
|
||||||
|
_, err = dec.Decode(&result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
limits := make([]BlockLimit, len(result.Limits))
|
||||||
|
for ix := range result.Limits {
|
||||||
|
limits[ix].Name = result.Limits[ix].Field
|
||||||
|
limits[ix].Value = binary.BigEndian.Uint64(result.Limits[ix].Value[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
return limits, nil
|
||||||
|
}
|
||||||
|
|
||||||
// lookup returns a domain as seen by libvirt.
|
// lookup returns a domain as seen by libvirt.
|
||||||
func (l *Libvirt) lookup(name string) (*Domain, error) {
|
func (l *Libvirt) lookup(name string) (*Domain, error) {
|
||||||
payload := struct {
|
payload := struct {
|
||||||
|
@ -437,3 +437,27 @@ func TestReset(t *testing.T) {
|
|||||||
t.Fatalf("unexpected reset error: %v", err)
|
t.Fatalf("unexpected reset error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetBlockIOTune(t *testing.T) {
|
||||||
|
conn := libvirttest.New()
|
||||||
|
l := New(conn)
|
||||||
|
|
||||||
|
if err := l.SetBlockIOTune("test", "vda", BlockLimit{"write_bytes_sec", 5000000}); err != nil {
|
||||||
|
t.Fatalf("unexpected SetBlockIOTune error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetBlockIOTune(t *testing.T) {
|
||||||
|
conn := libvirttest.New()
|
||||||
|
l := New(conn)
|
||||||
|
|
||||||
|
limits, err := l.GetBlockIOTune("do-test", "vda")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected GetBlockIOTune error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
lim := BlockLimit{"write_bytes_sec", 500000}
|
||||||
|
if limits[2] != lim {
|
||||||
|
t.Fatalf("unexpected result in limits list: %v", limits[2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -21,8 +21,9 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/digitalocean/go-libvirt/internal/constants"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/digitalocean/go-libvirt/internal/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testDomainResponse = []byte{
|
var testDomainResponse = []byte{
|
||||||
@ -399,6 +400,128 @@ var testRebootReply = []byte{
|
|||||||
0x00, 0x00, 0x00, 0x00, // status
|
0x00, 0x00, 0x00, 0x00, // status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var testSetBlockIoTuneReply = []byte{
|
||||||
|
0x00, 0x00, 0x00, 0x1c, // length
|
||||||
|
0x20, 0x00, 0x80, 0x86, // program
|
||||||
|
0x00, 0x00, 0x00, 0x01, // version
|
||||||
|
0x00, 0x00, 0x00, 0xfc, // procedure
|
||||||
|
0x00, 0x00, 0x00, 0x00, // type
|
||||||
|
0x00, 0x00, 0x00, 0x00, // serial
|
||||||
|
0x00, 0x00, 0x00, 0x00, // status
|
||||||
|
}
|
||||||
|
|
||||||
|
// This result block was obtained by calling `fmt.Printf("%#v", r.Payload)` on
|
||||||
|
// the result returned by an actual call to GetBlockIoTune, and then adding the
|
||||||
|
// standard header to the beginning. The length parameter has to be correct!
|
||||||
|
var testGetBlockIoTuneReply = []byte{
|
||||||
|
0x00, 0x00, 0x02, 0xe0, // length
|
||||||
|
0x20, 0x00, 0x80, 0x86, // program
|
||||||
|
0x00, 0x00, 0x00, 0x01, // version
|
||||||
|
0x00, 0x00, 0x00, 0xfd, // procedure
|
||||||
|
0x00, 0x00, 0x00, 0x00, // type
|
||||||
|
0x00, 0x00, 0x00, 0x00, // serial
|
||||||
|
0x00, 0x00, 0x00, 0x00, // status
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x13, // 13 TypedParams follow
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0xf, // field name is 15 bytes, padded to a multiple of 4
|
||||||
|
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4, // type
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // value
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0xe,
|
||||||
|
0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0xf,
|
||||||
|
0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xa1, 0x20,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0xe,
|
||||||
|
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0xd,
|
||||||
|
0x72, 0x65, 0x61, 0x64, 0x5f, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0xe,
|
||||||
|
0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x13,
|
||||||
|
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x12,
|
||||||
|
0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x13,
|
||||||
|
0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc3, 0x50,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x12,
|
||||||
|
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x11,
|
||||||
|
0x72, 0x65, 0x61, 0x64, 0x5f, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x12,
|
||||||
|
0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0xd,
|
||||||
|
0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x1a,
|
||||||
|
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x19,
|
||||||
|
0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x1a,
|
||||||
|
0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x19,
|
||||||
|
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x18,
|
||||||
|
0x72, 0x65, 0x61, 0x64, 0x5f, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x19,
|
||||||
|
0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x73, 0x65, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x4,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
|
||||||
|
0x0, 0x0, 0x0, 0x0, // End of TypedParams
|
||||||
|
}
|
||||||
|
|
||||||
// MockLibvirt provides a mock libvirt server for testing.
|
// MockLibvirt provides a mock libvirt server for testing.
|
||||||
type MockLibvirt struct {
|
type MockLibvirt struct {
|
||||||
net.Conn
|
net.Conn
|
||||||
@ -486,6 +609,10 @@ func (m *MockLibvirt) handleRemote(procedure uint32, conn net.Conn) {
|
|||||||
conn.Write(m.reply(testCreateWithFlags))
|
conn.Write(m.reply(testCreateWithFlags))
|
||||||
case constants.ProcDomainShutdownFlags:
|
case constants.ProcDomainShutdownFlags:
|
||||||
conn.Write(m.reply(testShutdownReply))
|
conn.Write(m.reply(testShutdownReply))
|
||||||
|
case constants.ProcDomainSetBlockIOTune:
|
||||||
|
conn.Write(m.reply(testSetBlockIoTuneReply))
|
||||||
|
case constants.ProcDomainGetBlockIOTune:
|
||||||
|
conn.Write(m.reply(testGetBlockIoTuneReply))
|
||||||
default:
|
default:
|
||||||
fmt.Fprintln(os.Stderr, "unknown procedure", procedure)
|
fmt.Fprintln(os.Stderr, "unknown procedure", procedure)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user