[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH RFC 7/8] golang/xenlight: Implement cpupool operations



Include some useful "Utility" functions:
- CpupoolFindByName
- CpupoolMakeFree

Still need to implement the following functions:
- libxl_cpupool_rename
- libxl_cpupool_cpuadd_node
- libxl_cpupool_cpuremove_node
- libxl_cpupool_movedomain
---
 tools/golang/xenlight/xenlight.go | 743 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 743 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 64e867a..215f49c 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -436,6 +436,749 @@ func (bm Bitmap) String() (s string) {
        return
 }
 
+// libxl_cpupoolinfo = Struct("cpupoolinfo", [
+//     ("poolid",      uint32),
+//     ("pool_name",   string),
+//     ("sched",       libxl_scheduler),
+//     ("n_dom",       uint32),
+//     ("cpumap",      libxl_bitmap)
+//     ], dir=DIR_OUT)
+
+type CpupoolInfo struct {
+       Poolid      uint32
+       PoolName    string
+       Scheduler   Scheduler
+       DomainCount int
+       Cpumap      Bitmap
+}
+
+func translateCpupoolInfoCToGo(cci C.libxl_cpupoolinfo) (gci CpupoolInfo) {
+       gci.Poolid = uint32(cci.poolid)
+       gci.PoolName = C.GoString(cci.pool_name)
+       gci.Scheduler = Scheduler(cci.sched)
+       gci.DomainCount = int(cci.n_dom)
+       gci.Cpumap = bitmapCToGo(cci.cpumap)
+
+       return
+}
+
+// # Consistent with values defined in domctl.h
+// # Except unknown which we have made up
+// libxl_scheduler = Enumeration("scheduler", [
+//     (0, "unknown"),
+//     (4, "sedf"),
+//     (5, "credit"),
+//     (6, "credit2"),
+//     (7, "arinc653"),
+//     (8, "rtds"),
+//     ])
+type Scheduler int
+
+var (
+       SchedulerUnknown  Scheduler = C.LIBXL_SCHEDULER_UNKNOWN
+       SchedulerSedf     Scheduler = C.LIBXL_SCHEDULER_SEDF
+       SchedulerCredit   Scheduler = C.LIBXL_SCHEDULER_CREDIT
+       SchedulerCredit2  Scheduler = C.LIBXL_SCHEDULER_CREDIT2
+       SchedulerArinc653 Scheduler = C.LIBXL_SCHEDULER_ARINC653
+       SchedulerRTDS     Scheduler = C.LIBXL_SCHEDULER_RTDS
+)
+
+// const char *libxl_scheduler_to_string(libxl_scheduler p);
+func (s Scheduler) String() string {
+       cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
+       // No need to free const return value
+
+       return C.GoString(cs)
+}
+
+// int libxl_scheduler_from_string(const char *s, libxl_scheduler *e);
+func (s *Scheduler) FromString(gstr string) (err error) {
+       cstr := C.CString(gstr)
+       defer C.free(unsafe.Pointer(cstr))
+
+       var cs C.libxl_scheduler
+       ret := C.libxl_scheduler_from_string(cstr, &cs)
+       if ret != 0 {
+               err = Errorxl(ret)
+               return
+       }
+
+       *s = Scheduler(cs)
+       return
+}
+
+func translateCpupoolInfoCToGo(cci C.libxl_cpupoolinfo) (gci CpupoolInfo) {
+       gci.Poolid = uint32(cci.poolid)
+       gci.PoolName = C.GoString(cci.pool_name)
+       gci.Scheduler = Scheduler(cci.sched)
+       gci.DomainCount = int(cci.n_dom)
+       gci.Cpumap = bitmapCToGo(cci.cpumap)
+
+       return
+}
+
+func SchedulerFromString(name string) (s Scheduler, err error) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+
+       var cs C.libxl_scheduler
+
+       ret := C.libxl_scheduler_from_string(cname, &cs)
+       if ret != 0 {
+               err = Errorxl(ret)
+               return
+       }
+
+       s = Scheduler(cs)
+
+       return
+}
+
+// typedef struct {
+//     uint32_t size;          /* number of bytes in map */
+//     uint8_t *map;
+// } libxl_bitmap;
+
+// Implement the Go bitmap type such that the underlying data can
+// easily be copied in and out.  NB that we still have to do copies
+// both directions, because cgo runtime restrictions forbid passing to
+// a C function a pointer to a Go-allocated structure which contains a
+// pointer.
+type Bitmap struct {
+       bitmap []C.uint8_t
+}
+
+/*
+ * Types: IDL
+ *
+ * FIXME: Generate these automatically from the IDL
+ */
+
+type Physinfo struct {
+       ThreadsPerCore    uint32
+       CoresPerSocket    uint32
+       MaxCpuId          uint32
+       NrCpus            uint32
+       CpuKhz            uint32
+       TotalPages        uint64
+       FreePages         uint64
+       ScrubPages        uint64
+       OutstandingPages  uint64
+       SharingFreedPages uint64
+       SharingUsedFrames uint64
+       NrNodes           uint32
+       HwCap             Hwcap
+       CapHvm            bool
+       CapHvmDirectio    bool
+}
+
+type VersionInfo struct {
+       XenVersionMajor int
+       XenVersionMinor int
+       XenVersionExtra string
+       Compiler        string
+       CompileBy       string
+       CompileDomain   string
+       CompileDate     string
+       Capabilities    string
+       Changeset       string
+       VirtStart       uint64
+       Pagesize        int
+       Commandline     string
+       BuildId         string
+}
+
+/*
+ * Bitmap operations
+ */
+
+// Return a Go bitmap which is a copy of the referred C bitmap.
+func bitmapCToGo(cbm C.libxl_bitmap) (gbm Bitmap) {
+       // Alloc a Go slice for the bytes
+       size := int(cbm.size)
+       gbm.bitmap = make([]C.uint8_t, size)
+
+       // Make a slice pointing to the C array
+       mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
+
+       // And copy the C array into the Go array
+       copy(gbm.bitmap, mapslice)
+
+       return
+}
+
+// Must be C.libxl_bitmap_dispose'd of afterwards
+func bitmapGotoC(gbm Bitmap) (cbm C.libxl_bitmap) {
+       C.libxl_bitmap_init(&cbm)
+
+       size := len(gbm.bitmap)
+       cbm._map = (*C.uint8_t)(C.malloc(C.size_t(size)))
+       cbm.size = C.uint32_t(size)
+       if cbm._map == nil {
+               panic("C.calloc failed!")
+       }
+
+       // Make a slice pointing to the C array
+       mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
+
+       // And copy the Go array into the C array
+       copy(mapslice, gbm.bitmap)
+
+       return
+}
+
+func (bm *Bitmap) Test(bit int) bool {
+       ubit := uint(bit)
+       if bit > bm.Max() || bm.bitmap == nil {
+               return false
+       }
+
+       return (bm.bitmap[bit/8] & (1 << (ubit & 7))) != 0
+}
+
+func (bm *Bitmap) Set(bit int) {
+       ibit := bit / 8
+       if ibit+1 > len(bm.bitmap) {
+               bm.bitmap = append(bm.bitmap, make([]C.uint8_t, 
ibit+1-len(bm.bitmap))...)
+       }
+
+       bm.bitmap[ibit] |= 1 << (uint(bit) & 7)
+}
+
+func (bm *Bitmap) SetRange(start int, end int) {
+       for i := start; i <= end; i++ {
+               bm.Set(i)
+       }
+}
+
+func (bm *Bitmap) Clear(bit int) {
+       ubit := uint(bit)
+       if bit > bm.Max() || bm.bitmap == nil {
+               return
+       }
+
+       bm.bitmap[bit/8] &= ^(1 << (ubit & 7))
+}
+
+func (bm *Bitmap) ClearRange(start int, end int) {
+       for i := start; i <= end; i++ {
+               bm.Clear(i)
+       }
+}
+
+func (bm *Bitmap) Max() int {
+       return len(bm.bitmap)*8 - 1
+}
+
+func (bm *Bitmap) IsEmpty() bool {
+       for i := 0; i < len(bm.bitmap); i++ {
+               if bm.bitmap[i] != 0 {
+                       return false
+               }
+       }
+       return true
+}
+
+func (a Bitmap) And(b Bitmap) (c Bitmap) {
+       var max, min int
+       if len(a.bitmap) > len(b.bitmap) {
+               max = len(a.bitmap)
+               min = len(b.bitmap)
+       } else {
+               max = len(b.bitmap)
+               min = len(a.bitmap)
+       }
+       c.bitmap = make([]C.uint8_t, max)
+
+       for i := 0; i < min; i++ {
+               c.bitmap[i] = a.bitmap[i] & b.bitmap[i]
+       }
+       return
+}
+
+func (bm Bitmap) String() (s string) {
+       lastOnline := false
+       crange := false
+       printed := false
+       var i int
+       /// --x-xxxxx-x -> 2,4-8,10
+       /// --x-xxxxxxx -> 2,4-10
+       for i = 0; i <= bm.Max(); i++ {
+               if bm.Test(i) {
+                       if !lastOnline {
+                               // Switching offline -> online, print this cpu
+                               if printed {
+                                       s += ","
+                               }
+                               s += fmt.Sprintf("%d", i)
+                               printed = true
+                       } else if !crange {
+                               // last was online, but we're not in a range; 
print -
+                               crange = true
+                               s += "-"
+                       } else {
+                               // last was online, we're in a range,  nothing 
else to do
+                       }
+                       lastOnline = true
+               } else {
+                       if lastOnline {
+                               // Switching online->offline; do we need to end 
a range?
+                               if crange {
+                                       s += fmt.Sprintf("%d", i-1)
+                               }
+                       }
+                       lastOnline = false
+                       crange = false
+               }
+       }
+       if lastOnline {
+               // Switching online->offline; do we need to end a range?
+               if crange {
+                       s += fmt.Sprintf("%d", i-1)
+               }
+       }
+
+       return
+}
+
+/*
+ * Context
+ */
+var Ctx Context
+
+func (Ctx *Context) IsOpen() bool {
+       return Ctx.ctx != nil
+}
+
+func (Ctx *Context) Open() (err error) {
+       if Ctx.ctx != nil {
+               return
+       }
+
+       ret := C.libxl_ctx_alloc(unsafe.Pointer(&Ctx.ctx), C.LIBXL_VERSION, 0, 
nil)
+
+       if ret != 0 {
+               err = Errorxl(ret)
+       }
+       return
+}
+
+func (Ctx *Context) Close() (err error) {
+       ret := C.libxl_ctx_free(unsafe.Pointer(Ctx.ctx))
+       Ctx.ctx = nil
+
+       if ret != 0 {
+               err = Errorxl(ret)
+       }
+       return
+}
+
+func (Ctx *Context) CheckOpen() (err error) {
+       if Ctx.ctx == nil {
+               err = fmt.Errorf("Context not opened")
+       }
+       return
+}
+
+//int libxl_get_max_cpus(libxl_ctx *ctx);
+func (Ctx *Context) GetMaxCpus() (maxCpus int, err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       ret := C.libxl_get_max_cpus(Ctx.ctx)
+       if ret < 0 {
+               err = Errorxl(ret)
+               return
+       }
+       maxCpus = int(ret)
+       return
+}
+
+//int libxl_get_online_cpus(libxl_ctx *ctx);
+func (Ctx *Context) GetOnlineCpus() (onCpus int, err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       ret := C.libxl_get_online_cpus(Ctx.ctx)
+       if ret < 0 {
+               err = Errorxl(ret)
+               return
+       }
+       onCpus = int(ret)
+       return
+}
+
+//int libxl_get_max_nodes(libxl_ctx *ctx);
+func (Ctx *Context) GetMaxNodes() (maxNodes int, err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+       ret := C.libxl_get_max_nodes(Ctx.ctx)
+       if ret < 0 {
+               err = Errorxl(ret)
+               return
+       }
+       maxNodes = int(ret)
+       return
+}
+
+//int libxl_get_free_memory(libxl_ctx *ctx, uint64_t *memkb);
+func (Ctx *Context) GetFreeMemory() (memkb uint64, err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+       var cmem C.uint64_t
+       ret := C.libxl_get_free_memory(Ctx.ctx, &cmem)
+
+       if ret < 0 {
+               err = Errorxl(ret)
+               return
+       }
+
+       memkb = uint64(cmem)
+       return
+
+}
+
+//int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo)
+func (Ctx *Context) GetPhysinfo() (physinfo *Physinfo, err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+       var cphys C.libxl_physinfo
+
+       ret := C.libxl_get_physinfo(Ctx.ctx, &cphys)
+
+       if ret < 0 {
+               err = Errorxl(ret)
+               return
+       }
+       physinfo = &Physinfo{}
+       physinfo.ThreadsPerCore = uint32(cphys.threads_per_core)
+       physinfo.CoresPerSocket = uint32(cphys.cores_per_socket)
+       physinfo.MaxCpuId = uint32(cphys.max_cpu_id)
+       physinfo.NrCpus = uint32(cphys.nr_cpus)
+       physinfo.CpuKhz = uint32(cphys.cpu_khz)
+       physinfo.TotalPages = uint64(cphys.total_pages)
+       physinfo.FreePages = uint64(cphys.free_pages)
+       physinfo.ScrubPages = uint64(cphys.scrub_pages)
+       physinfo.ScrubPages = uint64(cphys.scrub_pages)
+       physinfo.SharingFreedPages = uint64(cphys.sharing_freed_pages)
+       physinfo.SharingUsedFrames = uint64(cphys.sharing_used_frames)
+       physinfo.NrNodes = uint32(cphys.nr_nodes)
+       physinfo.HwCap = hwcapCToGo(cphys.hw_cap)
+       physinfo.CapHvm = bool(cphys.cap_hvm)
+       physinfo.CapHvmDirectio = bool(cphys.cap_hvm_directio)
+
+       return
+}
+
+//const libxl_version_info* libxl_get_version_info(libxl_ctx *ctx);
+func (Ctx *Context) GetVersionInfo() (info *VersionInfo, err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       var cinfo *C.libxl_version_info
+
+       cinfo = C.libxl_get_version_info(Ctx.ctx)
+
+       info = &VersionInfo{}
+       info.XenVersionMajor = int(cinfo.xen_version_major)
+       info.XenVersionMinor = int(cinfo.xen_version_minor)
+       info.XenVersionExtra = C.GoString(cinfo.xen_version_extra)
+       info.Compiler = C.GoString(cinfo.compiler)
+       info.CompileBy = C.GoString(cinfo.compile_by)
+       info.CompileDomain = C.GoString(cinfo.compile_domain)
+       info.CompileDate = C.GoString(cinfo.compile_date)
+       info.Capabilities = C.GoString(cinfo.capabilities)
+       info.Changeset = C.GoString(cinfo.changeset)
+       info.VirtStart = uint64(cinfo.virt_start)
+       info.Pagesize = int(cinfo.pagesize)
+       info.Commandline = C.GoString(cinfo.commandline)
+       info.BuildId = C.GoString(cinfo.build_id)
+
+       return
+}
+
+func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       var cdi C.libxl_dominfo
+
+       ret := C.libxl_domain_info(Ctx.ctx, unsafe.Pointer(&cdi), 
C.uint32_t(Id))
+
+       if ret != 0 {
+               err = Errorxl(ret)
+               return
+       }
+
+       // We could consider having this boilerplate generated by the
+       // idl, in a function like this:
+       //
+       // di = translateCdomaininfoToGoDomaininfo(cdi)
+       di = &Dominfo{}
+       di.Uuid = Uuid(cdi.uuid)
+       di.Domid = Domid(cdi.domid)
+       di.Ssidref = uint32(cdi.ssidref)
+       di.SsidLabel = C.GoString(cdi.ssid_label)
+       di.Running = bool(cdi.running)
+       di.Blocked = bool(cdi.blocked)
+       di.Paused = bool(cdi.paused)
+       di.Shutdown = bool(cdi.shutdown)
+       di.Dying = bool(cdi.dying)
+       di.NeverStop = bool(cdi.never_stop)
+       di.ShutdownReason = int32(cdi.shutdown_reason)
+       di.OutstandingMemkb = MemKB(cdi.outstanding_memkb)
+       di.CurrentMemkb = MemKB(cdi.current_memkb)
+       di.SharedMemkb = MemKB(cdi.shared_memkb)
+       di.PagedMemkb = MemKB(cdi.paged_memkb)
+       di.MaxMemkb = MemKB(cdi.max_memkb)
+       di.CpuTime = time.Duration(cdi.cpu_time)
+       di.VcpuMaxId = uint32(cdi.vcpu_max_id)
+       di.VcpuOnline = uint32(cdi.vcpu_online)
+       di.Cpupool = uint32(cdi.cpupool)
+       di.DomainType = int32(cdi.domain_type)
+
+       return
+}
+
+func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       ret := C.libxl_domain_unpause(Ctx.ctx, C.uint32_t(Id))
+
+       if ret != 0 {
+               err = Errorxl(ret)
+       }
+       return
+}
+
+// libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
+// void libxl_cpupoolinfo_list_free(libxl_cpupoolinfo *list, int nb_pool);
+func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
+       err := Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       var nbPool C.int
+
+       c_cpupool_list := C.libxl_list_cpupool(Ctx.ctx, &nbPool)
+
+       defer C.libxl_cpupoolinfo_list_free(c_cpupool_list, nbPool)
+
+       if int(nbPool) == 0 {
+               return
+       }
+
+       // Magic
+       cpupoolListSlice := (*[1 << 
30]C.libxl_cpupoolinfo)(unsafe.Pointer(c_cpupool_list))[:nbPool:nbPool]
+
+       for i := range cpupoolListSlice {
+               info := translateCpupoolInfoCToGo(cpupoolListSlice[i])
+
+               list = append(list, info)
+       }
+
+       return
+}
+
+// int libxl_cpupool_info(libxl_ctx *ctx, libxl_cpupoolinfo *info, uint32_t 
poolid);
+func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool CpupoolInfo) {
+       err := Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       var c_cpupool C.libxl_cpupoolinfo
+
+       ret := C.libxl_cpupool_info(Ctx.ctx, &c_cpupool, C.uint32_t(Poolid))
+       if ret != 0 {
+               err = Errorxl(ret)
+               return
+       }
+       defer C.libxl_cpupoolinfo_dispose(&c_cpupool)
+
+       pool = translateCpupoolInfoCToGo(c_cpupool)
+
+       return
+}
+
+// int libxl_cpupool_create(libxl_ctx *ctx, const char *name,
+//                          libxl_scheduler sched,
+//                          libxl_bitmap cpumap, libxl_uuid *uuid,
+//                          uint32_t *poolid);
+// FIXME: uuid
+// FIXME: Setting poolid
+func (Ctx *Context) CpupoolCreate(Name string, Scheduler Scheduler, Cpumap 
Bitmap) (err error, Poolid uint32) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       poolid := C.uint32_t(0)
+       name := C.CString(Name)
+       defer C.free(unsafe.Pointer(name))
+
+       // For now, just do what xl does, and make a new uuid every time we 
create the pool
+       var uuid C.libxl_uuid
+       C.libxl_uuid_generate(&uuid)
+
+       cbm := bitmapGotoC(Cpumap)
+       defer C.libxl_bitmap_dispose(&cbm)
+
+       ret := C.libxl_cpupool_create(Ctx.ctx, name, 
C.libxl_scheduler(Scheduler),
+               cbm, &uuid, &poolid)
+       if ret != 0 {
+               err = Errorxl(ret)
+               return
+       }
+
+       Poolid = uint32(poolid)
+
+       return
+}
+
+// int libxl_cpupool_destroy(libxl_ctx *ctx, uint32_t poolid);
+func (Ctx *Context) CpupoolDestroy(Poolid uint32) (err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       ret := C.libxl_cpupool_destroy(Ctx.ctx, C.uint32_t(Poolid))
+       if ret != 0 {
+               err = Errorxl(ret)
+               return
+       }
+
+       return
+}
+
+// int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu);
+func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) (err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       ret := C.libxl_cpupool_cpuadd(Ctx.ctx, C.uint32_t(Poolid), C.int(Cpu))
+       if ret != 0 {
+               err = Errorxl(ret)
+               return
+       }
+
+       return
+}
+
+// int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
+//                                 const libxl_bitmap *cpumap);
+func (Ctx *Context) CpupoolCpuaddCpumap(Poolid uint32, Cpumap Bitmap) (err 
error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       cbm := bitmapGotoC(Cpumap)
+       defer C.libxl_bitmap_dispose(&cbm)
+
+       ret := C.libxl_cpupool_cpuadd_cpumap(Ctx.ctx, C.uint32_t(Poolid), &cbm)
+       if ret != 0 {
+               err = Errorxl(ret)
+               return
+       }
+
+       return
+}
+
+// int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu);
+func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu int) (err error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       ret := C.libxl_cpupool_cpuremove(Ctx.ctx, C.uint32_t(Poolid), 
C.int(Cpu))
+       if ret != 0 {
+               err = Errorxl(ret)
+               return
+       }
+
+       return
+}
+
+// int libxl_cpupool_cpuremove_cpumap(libxl_ctx *ctx, uint32_t poolid,
+//                                    const libxl_bitmap *cpumap);
+func (Ctx *Context) CpupoolCpuremoveCpumap(Poolid uint32, Cpumap Bitmap) (err 
error) {
+       err = Ctx.CheckOpen()
+       if err != nil {
+               return
+       }
+
+       cbm := bitmapGotoC(Cpumap)
+       defer C.libxl_bitmap_dispose(&cbm)
+
+       ret := C.libxl_cpupool_cpuremove_cpumap(Ctx.ctx, C.uint32_t(Poolid), 
&cbm)
+       if ret != 0 {
+               err = Errorxl(ret)
+               return
+       }
+
+       return
+}
+
+// int libxl_cpupool_rename(libxl_ctx *ctx, const char *name, uint32_t poolid);
+// int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
+// int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
+// int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t 
domid);
+
+//
+// Utility functions
+//
+func (Ctx *Context) CpupoolFindByName(name string) (info CpupoolInfo, found 
bool) {
+       plist := Ctx.ListCpupool()
+
+       for i := range plist {
+               if plist[i].PoolName == name {
+                       found = true
+                       info = plist[i]
+                       return
+               }
+       }
+       return
+}
+
+func (Ctx *Context) CpupoolMakeFree(Cpumap Bitmap) (err error) {
+       plist := Ctx.ListCpupool()
+
+       for i := range plist {
+               var Intersection Bitmap
+               Intersection = Cpumap.And(plist[i].Cpumap)
+               if !Intersection.IsEmpty() {
+                       err = Ctx.CpupoolCpuremoveCpumap(plist[i].Poolid, 
Intersection)
+                       if err != nil {
+                               return
+                       }
+               }
+       }
+       return
+}
+
 /*
  * Context
  */
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.