Add DomainMemoryStats method (#38) (#39)

This commit is contained in:
Amanda H. L. de Andrade 2017-06-02 14:28:20 -03:00 committed by Ben LeMasurier
parent c09ce7b21d
commit 9ca7034516
5 changed files with 152 additions and 7 deletions

View File

@ -15,3 +15,4 @@ Charlie Drage <charlie@charliedrage.com>
Michael Koppmann <me@mkoppmann.at> Michael Koppmann <me@mkoppmann.at>
Simarpreet Singh <simar@linux.com> Simarpreet Singh <simar@linux.com>
Alexander Polyakov <apolyakov@beget.com> Alexander Polyakov <apolyakov@beget.com>
Amanda Andrade <amanda.andrade@serpro.gov.br>

View File

@ -46,6 +46,7 @@ const (
ProcStoragePoolRefresh = 83 ProcStoragePoolRefresh = 83
ProcStoragePoolLookupByName = 84 ProcStoragePoolLookupByName = 84
ProcConnectGetLibVersion = 157 ProcConnectGetLibVersion = 157
ProcDomainMemoryStats = 159
ProcDomainCreateWithFlags = 196 ProcDomainCreateWithFlags = 196
ProcDomainMigrateSetMaxSpeed = 207 ProcDomainMigrateSetMaxSpeed = 207
ProcDomainGetState = 212 ProcDomainGetState = 212

View File

@ -193,6 +193,7 @@ const (
// ShutdownFlags specifies options available when shutting down a domain. // ShutdownFlags specifies options available when shutting down a domain.
type ShutdownFlags uint32 type ShutdownFlags uint32
const ( const (
// ShutdownAcpiPowerBtn - send ACPI event // ShutdownAcpiPowerBtn - send ACPI event
ShutdownAcpiPowerBtn ShutdownFlags = 1 << iota ShutdownAcpiPowerBtn ShutdownFlags = 1 << iota
@ -301,6 +302,7 @@ const (
// RebootFlags specifies domain reboot methods // RebootFlags specifies domain reboot methods
type RebootFlags uint32 type RebootFlags uint32
const ( const (
// RebootAcpiPowerBtn - send ACPI event // RebootAcpiPowerBtn - send ACPI event
RebootAcpiPowerBtn RebootFlags = 1 << iota RebootAcpiPowerBtn RebootFlags = 1 << iota
@ -318,6 +320,54 @@ const (
RebootParavirt RebootParavirt
) )
// DomainMemoryStatTag specifies domain memory tags
type DomainMemoryStatTag uint32
const (
// DomainMemoryStatTagSwapIn - The total amount of data read from swap space (in kB).
DomainMemoryStatTagSwapIn DomainMemoryStatTag = iota
// DomainMemoryStatTagSwapOut - The total amount of memory written out to swap space (in kB).
DomainMemoryStatTagSwapOut
// DomainMemoryStatTagMajorFault - Page faults occur when a process makes a valid access to virtual memory
// that is not available. When servicing the page fault, if disk IO is
// required, it is considered a major fault.
// These are expressed as the number of faults that have occurred.
DomainMemoryStatTagMajorFault
// DomainMemoryStatTagMinorFault - If the page fault not require disk IO, it is a minor fault.
DomainMemoryStatTagMinorFault
// DomainMemoryStatTagUnused - The amount of memory left completely unused by the system (in kB).
DomainMemoryStatTagUnused
// DomainMemoryStatTagAvailable - The total amount of usable memory as seen by the domain (in kB).
DomainMemoryStatTagAvailable
// DomainMemoryStatTagActualBalloon - Current balloon value (in KB).
DomainMemoryStatTagActualBalloon
// DomainMemoryStatTagRss - Resident Set Size of the process running the domain (in KB).
DomainMemoryStatTagRss
// DomainMemoryStatTagUsable - How much the balloon can be inflated without pushing the guest system
// to swap, corresponds to 'Available' in /proc/meminfo
DomainMemoryStatTagUsable
// DomainMemoryStatTagLastUpdate - Timestamp of the last update of statistics, in seconds.
DomainMemoryStatTagLastUpdate
// DomainMemoryStatTagNr - The number of statistics supported by this version of the interface.
DomainMemoryStatTagNr
)
// DomainMemoryStat specifies memory stats of the domain
type DomainMemoryStat struct {
Tag DomainMemoryStatTag
Val uint64
}
// Capabilities returns an XML document describing the host's capabilties. // Capabilities returns an XML document describing the host's capabilties.
func (l *Libvirt) Capabilities() ([]byte, error) { func (l *Libvirt) Capabilities() ([]byte, error) {
resp, err := l.request(constants.ProcConnectGetCapabilties, constants.ProgramRemote, nil) resp, err := l.request(constants.ProcConnectGetCapabilties, constants.ProgramRemote, nil)
@ -430,6 +480,49 @@ func (l *Libvirt) DomainCreateWithFlags(dom string, flags DomainCreateFlags) err
return nil return nil
} }
// DomainMemoryStats returns memory stats of the domain managed by libvirt.
func (l *Libvirt) DomainMemoryStats(dom string) ([]DomainMemoryStat, error) {
d, err := l.lookup(dom)
if err != nil {
return nil, err
}
req := struct {
Domain Domain
MaxStats uint32
Flags uint32
}{
Domain: *d,
MaxStats: 8,
Flags: 0,
}
buf, err := encode(&req)
if err != nil {
return nil, err
}
resp, err := l.request(constants.ProcDomainMemoryStats, constants.ProgramRemote, &buf)
if err != nil {
return nil, err
}
r := <-resp
result := struct {
DomainMemoryStats []DomainMemoryStat
}{}
dec := xdr.NewDecoder(bytes.NewReader(r.Payload))
_, err = dec.Decode(&result)
if err != nil {
return nil, err
}
return result.DomainMemoryStats, nil
}
// DomainState returns state of the domain managed by libvirt. // DomainState returns state of the domain managed by libvirt.
func (l *Libvirt) DomainState(dom string) (DomainState, error) { func (l *Libvirt) DomainState(dom string) (DomainState, error) {
d, err := l.lookup(dom) d, err := l.lookup(dom)

View File

@ -133,6 +133,34 @@ func TestDomainState(t *testing.T) {
} }
} }
func TestDomainMemoryStats(t *testing.T) {
conn := libvirttest.New()
l := New(conn)
wantDomainMemoryStats := []DomainMemoryStat{
DomainMemoryStat{
Tag: 6,
Val: 1048576,
},
DomainMemoryStat{
Tag: 7,
Val: 91272,
},
}
gotDomainMemoryStats, err := l.DomainMemoryStats("test")
if err != nil {
t.Error(err)
}
for i := range wantDomainMemoryStats {
if wantDomainMemoryStats[i] != gotDomainMemoryStats[i] {
t.Errorf("expected domain memory stat %v, got %v", wantDomainMemoryStats[i], gotDomainMemoryStats[i])
}
}
}
func TestEvents(t *testing.T) { func TestEvents(t *testing.T) {
conn := libvirttest.New() conn := libvirttest.New()
l := New(conn) l := New(conn)

View File

@ -20,8 +20,8 @@ import (
"net" "net"
"sync/atomic" "sync/atomic"
"github.com/digitalocean/go-libvirt/internal/constants"
"fmt" "fmt"
"github.com/digitalocean/go-libvirt/internal/constants"
"os" "os"
) )
@ -207,6 +207,26 @@ var testDomainsReply = []byte{
0x00, 0x00, 0x02, 0x00, 0x00, 0x02,
} }
var testDomainMemoryStatsReply = []byte{
0x00, 0x00, 0x00, 0x38, // length
0x20, 0x00, 0x80, 0x86, // program
0x00, 0x00, 0x00, 0x01, // version
0x00, 0x00, 0x00, 0x9f, // procedure
0x00, 0x00, 0x00, 0x01, // type
0x00, 0x00, 0x00, 0x00, // serial
0x00, 0x00, 0x00, 0x00, // status
// tag 6 val 1048576
// tag 7 val 91272
0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x06,
0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07,
0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x64, 0x88,
}
var testDomainStateReply = []byte{ var testDomainStateReply = []byte{
0x00, 0x00, 0x00, 0x24, // length 0x00, 0x00, 0x00, 0x24, // length
0x20, 0x00, 0x80, 0x86, // program 0x20, 0x00, 0x80, 0x86, // program
@ -446,6 +466,8 @@ func (m *MockLibvirt) handleRemote(procedure uint32, conn net.Conn) {
conn.Write(m.reply(testSecretsReply)) conn.Write(m.reply(testSecretsReply))
case constants.ProcDomainGetState: case constants.ProcDomainGetState:
conn.Write(m.reply(testDomainStateReply)) conn.Write(m.reply(testDomainStateReply))
case constants.ProcDomainMemoryStats:
conn.Write(m.reply(testDomainMemoryStatsReply))
case constants.ProcDomainMigrateSetMaxSpeed: case constants.ProcDomainMigrateSetMaxSpeed:
conn.Write(m.reply(testSetSpeedReply)) conn.Write(m.reply(testSetSpeedReply))
case constants.ProcMigratePerformParams: case constants.ProcMigratePerformParams: