Re: [Xen-devel] [PATCH v4 01/14] golang/xenlight: Create stub package

2017-03-23 Thread Ronald Rojas
On Mon, Mar 20, 2017 at 05:51:03PM +, George Dunlap wrote:
> On Thu, Mar 16, 2017 at 7:08 PM, Ronald Rojas <ronlad...@gmail.com> wrote:
> > Create a basic Makefile to build and install libxenlight Golang
> > bindings. Also add a stub package which only opens libxl context.
> >
> > Include a global xenlight.Ctx variable which can be used as the
> > default context by the entire program if desired.
> >
> > For now, return simple errors. Proper error handling will be
> > added in next patch.
> >
> > Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
> > Signed-off-by: George Dunlap <george.dun...@citrix.com>
> > ---
> >
> > Changes:
> >
> > - Added global logger variable and destroyed the logger instance
> > when closing the context.
> >
> > - Whitespace fixes
> >
> > - Commented out CONFIG_GOLANG
> 
> > +# Go will do its own dependency checking, and not actuall go through
> > +# with the build if none of the input files have changed.
> > +#
> > +# NB that because the users of this library need to be able to
> > +# recompile the library from source, it needs to include '-lxenlight'
> > +# in the LDFLAGS; and thus we need to add -L$(XEN_XENLIGHT) here
> > +# so that it can find the actual library.
> > +.PHONY: build
> > +build: package
> > +   CGO_CFLAGS="$(CFLAGS_libxenlight) $(CFLAGS_libxentoollog)" 
> > CGO_LDFLAGS="$(LDLIBS_libxenlight) $(LDLIBS_libxentoollog)-L$(XEN_XENLIGHT) 
> > -L$(XEN_LIBXENTOOLLOG)" GOPATH=$(XEN_GOPATH) $(GO) install -x 
> > $(XEN_GOCODE_URL)/xenlight
> 
> Also, you're missing a space between `$(LDLIBS_libxentoollog)` and
> `-L$(XEN_XENLIGHT)`.  In the future please at least compile-test your
> code.
> 

Sorry! I rushed this patch, I'll fix this in the next iteration.

Ronald

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


Re: [Xen-devel] [PATCH v4 01/14] golang/xenlight: Create stub package

2017-03-23 Thread Ronald Rojas
On Mon, Mar 20, 2017 at 02:45:30PM +, George Dunlap wrote:
> On Thu, Mar 16, 2017 at 7:08 PM, Ronald Rojas <ronlad...@gmail.com> wrote:
> > Create a basic Makefile to build and install libxenlight Golang
> > bindings. Also add a stub package which only opens libxl context.
> >
> > Include a global xenlight.Ctx variable which can be used as the
> > default context by the entire program if desired.
> >
> > For now, return simple errors. Proper error handling will be
> > added in next patch.
> >
> > Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
> > Signed-off-by: George Dunlap <george.dun...@citrix.com>
> 
> Almost there.  One comment on one of the last changes...
> 
 
 [snip]

> I think we want xenlight.Ctx to contain all the information needed to
> open and close it; as long as we're creating a logger automatically,
> we should store the pointer to the logger in the Ctx struct.
> 
> We should also set the pointer to nil after calling
> xtl_logger_destroy() to prevent use-after-free bugs.
> 
> (Yay lack of garbage collection again.)

Makes sense. I'll put the logger inside the Ctx struct.

Ronald

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


[Xen-devel] [PATCH v4 07/14] golang/xenlight: Implement libxl_scheduler enumeration

2017-03-16 Thread Ronald Rojas
Include both constants and a Stringification for libxl_scheduler.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
 tools/golang/xenlight/xenlight.go | 62 +++
 1 file changed, 62 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index eb2b3cf..d4a6bc1 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -311,6 +311,68 @@ func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
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, )
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   *s = Scheduler(cs)
+   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, )
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   s = Scheduler(cs)
+
+   return
+}
+
 /*
  * Bitmap operations
  */
-- 
2.7.3


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


[Xen-devel] [PATCH v4 09/14] golang/xenlight: Implement Domain operations

2017-03-16 Thread Ronald Rojas
Add calls for the following Domain related functionality
- libxl_domain_pause
- libxl_domain_shutdown
- libxl_domain_reboot
- libxl_list_domain

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 70 +++
 1 file changed, 70 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 85e4c78..5a1e273 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -956,3 +956,73 @@ func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
}
return
 }
+
+//int libxl_domain_pause(libxl_ctx *ctx, uint32_t domain);
+func (Ctx *Context) DomainPause(id Domid) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   ret := C.libxl_domain_pause(Ctx.ctx, C.uint32_t(id))
+
+   if ret != 0 {
+   err = Error(-ret)
+   }
+   return
+}
+
+//int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid);
+func (Ctx *Context) DomainShutdown(id Domid) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   ret := C.libxl_domain_shutdown(Ctx.ctx, C.uint32_t(id))
+
+   if ret != 0 {
+   err = Error(-ret)
+   }
+   return
+}
+
+//int libxl_domain_reboot(libxl_ctx *ctx, uint32_t domid);
+func (Ctx *Context) DomainReboot(id Domid) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   ret := C.libxl_domain_reboot(Ctx.ctx, C.uint32_t(id))
+
+   if ret != 0 {
+   err = Error(-ret)
+   }
+   return
+}
+
+//libxl_dominfo * libxl_list_domain(libxl_ctx*, int *nb_domain_out);
+//void libxl_dominfo_list_free(libxl_dominfo *list, int nb_domain);
+func (Ctx *Context) ListDomain() (glist []Dominfo) {
+   err := Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var nbDomain C.int
+   clist := C.libxl_list_domain(Ctx.ctx, )
+   defer C.libxl_dominfo_list_free(clist, nbDomain)
+
+   if int(nbDomain) == 0 {
+   return
+   }
+
+   gslice := (*[1 << 
30]C.libxl_dominfo)(unsafe.Pointer(clist))[:nbDomain:nbDomain]
+   for i := range gslice {
+   info := gslice[i].toGo()
+   glist = append(glist, *info)
+   }
+
+   return
+}
-- 
2.7.3


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


[Xen-devel] [PATCH v4 13/14] golang/xenlight: Implement ActionOnShutdown and DomainConfig

2017-03-16 Thread Ronald Rojas
Applied enumeration and implemented toC method for ActionOnShutdown

Implemented struct and implemented toC method for DomainConfig

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 61 +++
 1 file changed, 61 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 8b5ca38..ed76fec 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -1299,3 +1299,64 @@ type DeviceUsbdev struct {
 func (gdu DeviceUsbdev) toC() (cdu C.libxl_device_usbdev) {
return
 }
+
+type ActionOnShutdown int
+
+const (
+   ActionOnShutdownDestroy = C.LIBXL_ACTION_ON_SHUTDOWN_DESTROY
+   ActionOnShutdownRestart = C.LIBXL_ACTION_ON_SHUTDOWN_RESTART
+   ActionOnShutdownRestartRename   = 
C.LIBXL_ACTION_ON_SHUTDOWN_RESTART_RENAME
+   ActionOnShutdownPreserve= C.LIBXL_ACTION_ON_SHUTDOWN_PRESERVE
+   ActionOnShutdownCoredumpDestroy = 
C.LIBXL_ACTION_ON_SHUTDOWN_COREDUMP_DESTROY
+   ActionOnShutdownCoredumRestart  = 
C.LIBXL_ACTION_ON_SHUTDOWN_COREDUMP_RESTART
+   ActionOnShutdownSoftReset   = C.LIBXL_ACTION_ON_SHUTDOWN_SOFT_RESET
+)
+
+func (aos ActionOnShutdown) String() (str string) {
+   cstr := 
C.libxl_action_on_shutdown_to_string(C.libxl_action_on_shutdown(aos))
+
+   str = C.GoString(cstr)
+
+   return
+}
+
+func (gaos ActionOnShutdown) toC() (caos C.libxl_action_on_shutdown) {
+   caos = C.libxl_action_on_shutdown(gaos)
+   return
+}
+
+type DomainConfig struct {
+   CInfo DomainCreateInfo
+   BInfo DomainBuildInfo
+
+   Disks   []DeviceNic
+   Pcidevs []DevicePci
+   Rdms[]DeviceRdm
+   Dtdevs  []DeviceDtdev
+   Vftbs   []DeviceVfb
+   Vkbs[]DeviceVkb
+   Vtpms   []DeviceVtpm
+
+   Channels []DeviceChannel
+   Usbctrls []DeviceUsbctrl
+   Usbdevs  []DeviceUsbdev
+
+   OnPoweroff  ActionOnShutdown
+   OnRebootActionOnShutdown
+   OnWatchdog  ActionOnShutdown
+   OnCrash ActionOnShutdown
+   OnSoftReset ActionOnShutdown
+}
+
+func (gdc DomainConfig) toC() (cdc C.libxl_domain_config) {
+   cdc.c_info = gdc.CInfo.toC()
+   cdc.b_info = gdc.BInfo.toC()
+   //FIXME: Implement converting device information
+
+   cdc.on_poweroff = gdc.OnPoweroff.toC()
+   cdc.on_reboot = gdc.OnReboot.toC()
+   cdc.on_watchdog = gdc.OnWatchdog.toC()
+   cdc.on_crash = gdc.OnCrash.toC()
+   cdc.on_soft_reset = gdc.OnSoftReset.toC()
+   return
+}
-- 
2.7.3


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


[Xen-devel] [PATCH v4 11/14] golang/xenlight: Implement get console path operations

2017-03-16 Thread Ronald Rojas
Implement Golang enumeration of libxl_console_type
as ConsoleType

Implement the following libxl functions:
- libxl_console_get_tty
- libxl_primary_console_get_tty

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 57 +++
 1 file changed, 57 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 61d7f8f..d520f74 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -1080,3 +1080,60 @@ func (Ctx *Context) ListVcpu(id Domid) (glist 
[]Vcpuinfo) {
 
return
 }
+
+type ConsoleType int
+
+const (
+   ConsoleTypeUnknown = ConsoleType(C.LIBXL_CONSOLE_TYPE_UNKNOWN)
+   ConsoleTypeSerial  = ConsoleType(C.LIBXL_CONSOLE_TYPE_SERIAL)
+   ConsoleTypePV  = ConsoleType(C.LIBXL_CONSOLE_TYPE_PV)
+)
+
+func (ct ConsoleType) String() (str string) {
+   cstr := C.libxl_console_type_to_string(C.libxl_console_type(ct))
+   str = C.GoString(cstr)
+
+   return
+}
+
+//int libxl_console_get_tty(libxl_ctx *ctx, uint32_t domid, int cons_num,
+//libxl_console_type type, char **path);
+func (Ctx *Context) ConsoleGetTty(id Domid, consNum int, conType ConsoleType) 
(path string, err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var cpath *C.char
+   defer C.free(cpath)
+   ret := C.libxl_console_get_tty(Ctx.ctx, C.uint32_t(id), C.int(consNum), 
C.libxl_console_type(conType), )
+
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   path = C.GoString(cpath)
+   return
+}
+
+//int libxl_primary_console_get_tty(libxl_ctx *ctx, uint32_t domid_vm,
+// char **path);
+func (Ctx *Context) PrimaryConsoleGetTty(domid uint32) (path string, err 
error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var cpath *C.char
+   ret := C.libxl_primary_console_get_tty(Ctx.ctx, C.uint32_t(domid), 
)
+   defer C.free(cpath)
+
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   path = C.GoString(cpath)
+   return
+}
-- 
2.7.3


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


[Xen-devel] [PATCH v4 12/14] golang/xenlight: Created boilerplate code for device related structs

2017-03-16 Thread Ronald Rojas
Created boilerplate struct and toC methods for the
following structs:
- KeyValueList
- DomainBuildInfo
- DeviceNic
- DevicePci
- DeviceRdm
- DeviceDtdev
- DeviceVfb
- DeviceVkb
- DeviceVtpm
- DeviceChannel
- DeviceUsbctrl
- DeviceUsbdev

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
This specific patch constains mostly boilerplate code
that will be implemented in patches later down the road.

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 162 ++
 1 file changed, 162 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index d520f74..8b5ca38 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -1137,3 +1137,165 @@ func (Ctx *Context) PrimaryConsoleGetTty(domid uint32) 
(path string, err error)
path = C.GoString(cpath)
return
 }
+
+type Defbool string
+
+type KeyValueList []string
+
+type ckeyvaluelist struct {
+   clist C.libxl_key_value_list
+}
+
+func (clist ckeyvaluelist) toGo(glist KeyValueList) {
+   return
+}
+
+type DomainCreateInfo struct {
+   Type  DomainType
+   Hap   Defbool
+   Oos   Defbool
+   ssidref   uint32
+   ssid_labelstring
+   name  string
+   uuid  Uuid
+   XsdataKeyValueList
+   Platformdata  KeyValueList
+   Pooliduint32
+   PoolName  string
+   RunHotplugScripts Defbool
+   Pvh   Defbool
+   DriverDomain  Defbool
+}
+
+func (dci DomainCreateInfo) toC() (cci C.libxl_domain_create_info) {
+
+   return
+}
+
+type TscMode int
+
+const (
+   TscModeDefault= TscMode(C.LIBXL_TSC_MODE_DEFAULT)
+   TscModeAlwaysEmulate  = TscMode(C.LIBXL_TSC_MODE_ALWAYS_EMULATE)
+   TscModeNative = TscMode(C.LIBXL_TSC_MODE_NATIVE)
+   TscModeNativeParavirt = TscMode(C.LIBXL_TSC_MODE_NATIVE_PARAVIRT)
+)
+
+func (tm TscMode) String() (str string) {
+   cstr := C.libxl_tsc_mode_to_string(C.libxl_tsc_mode(tm))
+   str = C.GoString(cstr)
+
+   return
+}
+
+type CpuidPolicy struct {
+   //FIXME: Implement struct
+}
+
+//FIXME Create toGo function for CpuidPolicy
+
+type DomainBuildInfo struct {
+   MaxVcpus int
+   AvailVcpus   Bitmap
+   Cpumap   Bitmap
+   Nodemap  Bitmap
+   VcpuHardAffinity []Bitmap
+   VcpuSoftAffinity []Bitmap
+   NumaPlacementDefbool
+   TscMode  TscMode
+   MaxMemkb MemKB
+   TargetMemkb  MemKB
+   VideoMemkb   MemKB
+   ShadowMemkb  MemKB
+   RtcTimeoffsetuint32
+   ExecSsidref  uint32
+   ExecSsidLabelstring
+   localTimeDefbool
+   DisableMigrate   Defbool
+   Cpuid[]CpuidPolicy
+   blkdevStart  string
+}
+
+func (gdbi DomainBuildInfo) toC() (cdbi C.libxl_domain_build_info) {
+   return
+}
+
+type DeviceNic struct {
+   //FIXME: complete struct
+}
+
+func (gdn DeviceNic) toC() (cdn C.libxl_device_nic) {
+   return
+}
+
+type DevicePci struct {
+   //FIXME: complete struct
+}
+
+func (gdp DevicePci) toC() (cdp C.libxl_device_pci) {
+   return
+}
+
+type DeviceRdm struct {
+   //FIXME: complete struct
+}
+
+func (gdr DeviceRdm) toC() (cdr C.libxl_device_rdm) {
+   return
+}
+
+type DeviceDtdev struct {
+   //FIXME: complete struct
+}
+
+func (gdd DeviceDtdev) toC() (cdd C.libxl_device_dtdev) {
+   return
+}
+
+type DeviceVfb struct {
+   //FIXME: complete struct
+}
+
+func (gdv DeviceVfb) toC() (cdv C.libxl_device_vfb) {
+   return
+}
+
+type DeviceVkb struct {
+   //FIXME: complete struct
+}
+
+func (gdv DeviceVkb) toC() (cdv C.libxl_device_vkb) {
+   return
+}
+
+type DeviceVtpm struct {
+   //FIXME: complete struct
+}
+
+func (gdv DeviceVtpm) toC() (cdv C.libxl_device_vtpm) {
+   return
+}
+
+type DeviceChannel struct {
+   //FIXME: complete struct
+}
+
+func (gdc DeviceChannel) toC() (cdc C.libxl_device_channel) {
+   return
+}
+
+type DeviceUsbctrl struct {
+   //FIXME: complete struct
+}
+
+func (gdu DeviceUsbctrl) toC() (cdu C.libxl_device_usbctrl) {
+   return
+}
+
+type DeviceUsbdev struct {
+   //FIXME: complete struct
+}
+
+func (gdu DeviceUsbdev) toC() (cdu C.libxl_device_usbdev) {
+   return
+}
-- 
2.7.3


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


[Xen-devel] [PATCH v4 14/14] golang/xenlight: Implement domain create/destroy operations

2017-03-16 Thread Ronald Rojas
Implemented DomainCreateNew and DomainDestroy methods

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index ed76fec..c9774cf 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -1360,3 +1360,46 @@ func (gdc DomainConfig) toC() (cdc 
C.libxl_domain_config) {
cdc.on_soft_reset = gdc.OnSoftReset.toC()
return
 }
+
+//int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config,
+// uint32_t *domid,
+// const libxl_asyncop_how *ao_how,
+// const libxl_asyncprogress_how *aop_console_how)
+// LIBXL_EXTERNAL_CALLERS_ONLY;
+func (Ctx *Context) DomainCreateNew(dconfig DomainConfig) (id Domid, err 
error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+   cconfig := dconfig.toC()
+
+   var cid C.uint32_t
+   //FIXME: create async caller
+   ret := C.libxl_domain_create_new(Ctx.ctx, , , nil, nil)
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+   id = Domid(cid)
+
+   return
+}
+
+//int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid,
+// const libxl_asyncop_how *ao_how)
+// LIBXL_EXTERNAL_CALLERS_ONLY;
+func (Ctx *Context) DomainDestroy(id Domid) (err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   //FIXME: create async caller
+   ret := C.libxl_domain_destroy(Ctx.ctx, C.uint32_t(id), nil)
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+   return
+
+}
-- 
2.7.3


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


[Xen-devel] [PATCH v4 10/14] golang/xenlight: Implement Vcpuinfo and ListVcpu

2017-03-16 Thread Ronald Rojas
Include Golang version of libxl_vcpu_info
as VcpuInfo

Add a Golang call for libxl_list_vcpu as
ListVcpu

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 54 +++
 1 file changed, 54 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 5a1e273..61d7f8f 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -1026,3 +1026,57 @@ func (Ctx *Context) ListDomain() (glist []Dominfo) {
 
return
 }
+
+type Vcpuinfo struct {
+   Vcpuid uint32
+   Cpuuint32
+   Online bool
+   Blockedbool
+   Runningbool
+   VCpuTime   time.Duration
+   Cpumap Bitmap
+   CpumapSoft Bitmap
+}
+
+func (cvci C.libxl_vcpuinfo) toGo() (gvci Vcpuinfo) {
+   gvci.Vcpuid = uint32(cvci.vcpuid)
+   gvci.Cpu = uint32(cvci.cpu)
+   gvci.Online = bool(cvci.online)
+   gvci.Blocked = bool(cvci.blocked)
+   gvci.Running = bool(cvci.running)
+   gvci.VCpuTime = time.Duration(cvci.vcpu_time)
+   gvci.Cpumap = cvci.cpumap.toGo()
+   gvci.CpumapSoft = cvci.cpumap_soft.toGo()
+
+   return
+}
+
+//libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid,
+// int *nb_vcpu, int *nr_cpus_out);
+//void libxl_vcpuinfo_list_free(libxl_vcpuinfo *, int nr_vcpus);
+func (Ctx *Context) ListVcpu(id Domid) (glist []Vcpuinfo) {
+   err := Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var nbVcpu C.int
+   var nrCpu C.int
+
+   clist := C.libxl_list_vcpu(Ctx.ctx, C.uint32_t(id), , )
+   defer C.libxl_vcpuinfo_list_free(clist, nbVcpu)
+
+   if int(nbVcpu) == 0 {
+   return
+   }
+
+   gslice := (*[1 << 
30]C.libxl_vcpuinfo)(unsafe.Pointer(clist))[:nbVcpu:nbVcpu]
+
+   for i := range gslice {
+   info := gslice[i].toGo()
+
+   glist = append(glist, info)
+   }
+
+   return
+}
-- 
2.7.3


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


[Xen-devel] [PATCH v4 08/14] golang/xenlight: Implement cpupool operations

2017-03-16 Thread Ronald Rojas
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

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>

---

Changes

- Renamed CToGo functions as toGo

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 237 ++
 1 file changed, 237 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index d4a6bc1..85e4c78 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -373,6 +373,243 @@ func SchedulerFromString(name string) (s Scheduler, err 
error) {
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
+   PoolNamestring
+   Scheduler   Scheduler
+   DomainCount int
+   Cpumap  Bitmap
+}
+
+func (cci C.libxl_cpupoolinfo) toGo() (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 = cci.cpumap.toGo()
+
+   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, )
+
+   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 := cpupoolListSlice[i].toGo()
+
+   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, _cpupool, C.uint32_t(Poolid))
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+   defer C.libxl_cpupoolinfo_dispose(_cpupool)
+
+   pool = c_cpupool.toGo()
+
+   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()
+
+   cbm := Cpumap.toC()
+   defer C.libxl_bitmap_dispose()
+
+   ret := C.libxl_cpupool_create(Ctx.ctx, name, 
C.libxl_scheduler(Scheduler),
+   cbm, , )
+   if ret != 0 {
+   err = Error(-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 = Error(-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 = Error(-ret)
+   return
+   }
+

[Xen-devel] [PATCH v4 06/14] golang/xenlight: Implement libxl_bitmap and helper operations

2017-03-16 Thread Ronald Rojas
Implement Bitmap type, along with helper functions.

The Bitmap type is implemented interllay in a way which makes it
easy to copy into and out of the C libxl_bitmap type.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>

---

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com

---
---
 tools/golang/xenlight/xenlight.go | 167 ++
 1 file changed, 167 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 34c3050..eb2b3cf 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -129,6 +129,20 @@ func (chwcap C.libxl_hwcap) toGo() (ghwcap Hwcap) {
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
  *
@@ -298,6 +312,159 @@ func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
 }
 
 /*
+ * Bitmap operations
+ */
+
+// Return a Go bitmap which is a copy of the referred C bitmap.
+func (cbm C.libxl_bitmap) toGo() (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 (gbm Bitmap) toC() (cbm C.libxl_bitmap) {
+   C.libxl_bitmap_init()
+
+   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-x-x -> 2,4-8,10
+   /// --x-xxx -> 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 {
+   //

[Xen-devel] [PATCH v4 04/14] golang/xenlight: Implement libxl_domain_info and libxl_domain_unpause

2017-03-16 Thread Ronald Rojas
Add calls for the following host-related functionality:
- libxl_domain_info
- libxl_domain_unpause

Include Golang version for the libxl_domain_info as
DomainInfo.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
Changes since last version

- Formating fixes

- used defer for libxl_dominfo_dispose

- Removed unnessary unsafe.Pointer() casts.

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com

---
---
 tools/golang/xenlight/xenlight.go | 136 +-
 1 file changed, 133 insertions(+), 3 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 785eaaf..34c3050 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -33,6 +33,7 @@ import "C"
 
 import (
"fmt"
+   "time"
"unsafe"
 )
 
@@ -102,13 +103,19 @@ var errors = [...]string{
  * Types: Builtins
  */
 
+type Domid uint32
+
+type MemKB uint64
+
+type Uuid C.libxl_uuid
+
 type Context struct {
ctx *C.libxl_ctx
 }
 
 type Hwcap []C.uint32_t
 
-func (chwcap C.libxl_hwcap) CToGo() (ghwcap Hwcap) {
+func (chwcap C.libxl_hwcap) toGo() (ghwcap Hwcap) {
// Alloc a Go slice for the bytes
size := 8
ghwcap = make([]C.uint32_t, size)
@@ -161,7 +168,7 @@ func (cphys *C.libxl_physinfo) toGo() (physinfo *Physinfo) {
physinfo.SharingFreedPages = uint64(cphys.sharing_freed_pages)
physinfo.SharingUsedFrames = uint64(cphys.sharing_used_frames)
physinfo.NrNodes = uint32(cphys.nr_nodes)
-   physinfo.HwCap = cphys.hw_cap.CToGo()
+   physinfo.HwCap = cphys.hw_cap.toGo()
physinfo.CapHvm = bool(cphys.cap_hvm)
physinfo.CapHvmDirectio = bool(cphys.cap_hvm_directio)
 
@@ -203,6 +210,93 @@ func (cinfo *C.libxl_version_info) toGo() (info 
*VersionInfo) {
return
 }
 
+type ShutdownReason int32
+
+const (
+   ShutdownReasonUnknown   = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_UNKNOWN)
+   ShutdownReasonPoweroff  = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_POWEROFF)
+   ShutdownReasonReboot= ShutdownReason(C.LIBXL_SHUTDOWN_REASON_REBOOT)
+   ShutdownReasonSuspend   = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SUSPEND)
+   ShutdownReasonCrash = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_CRASH)
+   ShutdownReasonWatchdog  = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_WATCHDOG)
+   ShutdownReasonSoftReset = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SOFT_RESET)
+)
+
+func (sr ShutdownReason) String() (str string) {
+   cstr := C.libxl_shutdown_reason_to_string(C.libxl_shutdown_reason(sr))
+   str = C.GoString(cstr)
+
+   return
+}
+
+type DomainType int32
+
+const (
+   DomainTypeInvalid = DomainType(C.LIBXL_DOMAIN_TYPE_INVALID)
+   DomainTypeHvm = DomainType(C.LIBXL_DOMAIN_TYPE_HVM)
+   DomainTypePv  = DomainType(C.LIBXL_DOMAIN_TYPE_PV)
+)
+
+func (dt DomainType) String() (str string) {
+   cstr := C.libxl_domain_type_to_string(C.libxl_domain_type(dt))
+   str = C.GoString(cstr)
+
+   return
+}
+
+type Dominfo struct {
+   Uuid  Uuid
+   Domid Domid
+   Ssidref   uint32
+   SsidLabel string
+   Running   bool
+   Blocked   bool
+   Pausedbool
+   Shutdown  bool
+   Dying bool
+   NeverStop bool
+
+   ShutdownReason   int32
+   OutstandingMemkb MemKB
+   CurrentMemkb MemKB
+   SharedMemkb  MemKB
+   PagedMemkb   MemKB
+   MaxMemkb MemKB
+   CpuTime  time.Duration
+   VcpuMaxIduint32
+   VcpuOnline   uint32
+   Cpupool  uint32
+   DomainType   int32
+}
+
+func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
+
+   di = {}
+   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
+}
+
 /*
  * Context
  */
@@ -332,6 +426,7 @@ func (Ctx *Context) GetPhysinfo() (physinfo *Physinfo, err 
error) {
}
var 

[Xen-devel] [PATCH v4 01/14] golang/xenlight: Create stub package

2017-03-16 Thread Ronald Rojas
Create a basic Makefile to build and install libxenlight Golang
bindings. Also add a stub package which only opens libxl context.

Include a global xenlight.Ctx variable which can be used as the
default context by the entire program if desired.

For now, return simple errors. Proper error handling will be
added in next patch.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
Signed-off-by: George Dunlap <george.dun...@citrix.com>
---

Changes:

- Added global logger variable and destroyed the logger instance
when closing the context.

- Whitespace fixes

- Commented out CONFIG_GOLANG

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/Makefile|  1 +
 tools/Rules.mk|  7 
 tools/golang/Makefile | 27 
 tools/golang/xenlight/Makefile| 49 ++
 tools/golang/xenlight/xenlight.go | 88 +++
 5 files changed, 172 insertions(+)
 create mode 100644 tools/golang/Makefile
 create mode 100644 tools/golang/xenlight/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 77e0723..df1fda1 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -31,6 +31,7 @@ endif
 
 SUBDIRS-y += xenpmd
 SUBDIRS-y += libxl
+SUBDIRS-$(CONFIG_GOLANG) += golang
 SUBDIRS-y += helpers
 SUBDIRS-$(CONFIG_X86) += xenpaging
 SUBDIRS-$(CONFIG_X86) += debugger/gdbsx
diff --git a/tools/Rules.mk b/tools/Rules.mk
index b35999b..4edffbe 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -30,6 +30,13 @@ XENSTORE_XENSTORED ?= y
 debug ?= y
 debug_symbols ?= $(debug)
 
+# Uncomment to compile with Go
+#CONFIG_GOLANG ?= y
+ifeq ($(CONFIG_GOLANG),y)
+XEN_GOPATH= $(XEN_ROOT)/tools/golang
+XEN_GOCODE_URL= golang.xenproject.org
+endif
+
 ifeq ($(debug_symbols),y)
 CFLAGS += -g3
 endif
diff --git a/tools/golang/Makefile b/tools/golang/Makefile
new file mode 100644
index 000..47a9235
--- /dev/null
+++ b/tools/golang/Makefile
@@ -0,0 +1,27 @@
+XEN_ROOT=$(CURDIR)/../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+# In order to link against a package in Go, the package must live in a
+# directory tree in the way that Go expects.  To make this possible,
+# there must be a directory such that we can set GOPATH=${dir}, and
+# the package will be under $GOPATH/src/${full-package-path}.
+
+# So we set XEN_GOPATH to $XEN_ROOT/tools/golang.  The xenlight
+# "package build" directory ($PWD/xenlight) will create the "package
+# source" directory in the proper place.  Go programs can use this
+# package by setting GOPATH=$(XEN_GOPATH).
+
+SUBDIRS-y = xenlight
+
+.PHONY: build all
+all build: subdirs-all
+
+.PHONY: install
+install: subdirs-install
+
+.PHONY: clean
+clean: subdirs-clean
+   $(RM) -r src pkg
+
+.PHONY: distclean
+distclean: clean
diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
new file mode 100644
index 000..5db665d
--- /dev/null
+++ b/tools/golang/xenlight/Makefile
@@ -0,0 +1,49 @@
+XEN_ROOT=$(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+# Standing boldly against convention, we insist on installing the
+# package source under $(prefix)/share/gocode
+GOCODE_DIR ?= $(prefix)/share/gocode/
+GOXL_PKG_DIR = /src/$(XEN_GOCODE_URL)/xenlight/
+GOXL_INSTALL_DIR = $(GOCODE_DIR)$(GOXL_PKG_DIR)
+
+# PKGSOURCES: Files which comprise the distributed source package
+PKGSOURCES = xenlight.go
+
+GO ?= go
+
+.PHONY: all
+all: build
+
+.PHONY: package
+package: $(XEN_GOPATH)$(GOXL_PKG_DIR)$(PKGSOURCES)
+
+$(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/$(PKGSOURCES): $(PKGSOURCES)
+   $(INSTALL_DIR) $(XEN_GOPATH)$(GOXL_PKG_DIR)
+   $(INSTALL_DATA) $(PKGSOURCES) $(XEN_GOPATH)$(GOXL_PKG_DIR)
+
+# Go will do its own dependency checking, and not actuall go through
+# with the build if none of the input files have changed.
+#
+# NB that because the users of this library need to be able to
+# recompile the library from source, it needs to include '-lxenlight'
+# in the LDFLAGS; and thus we need to add -L$(XEN_XENLIGHT) here
+# so that it can find the actual library.
+.PHONY: build
+build: package
+   CGO_CFLAGS="$(CFLAGS_libxenlight) $(CFLAGS_libxentoollog)" 
CGO_LDFLAGS="$(LDLIBS_libxenlight) $(LDLIBS_libxentoollog)-L$(XEN_XENLIGHT) 
-L$(XEN_LIBXENTOOLLOG)" GOPATH=$(XEN_GOPATH) $(GO) install -x 
$(XEN_GOCODE_URL)/xenlight
+
+.PHONY: install
+install: build
+   $(INSTALL_DIR) $(DESTDIR)$(GOXL_INSTALL_DIR)
+   $(INSTALL_DATA) $(XEN_GOPATH)$(GOXL_PKG_DIR)$(PKGSOURCES) 
$(DESTDIR)$(GOXL_INSTALL_DIR)
+
+.PHONY: clean
+clean:
+   $(RM) -r $(XEN_GOPATH)$(GOXL_PKG_DIR)
+   $(RM) $(XEN_GOPATH)/pkg/*/$(XEN_GOCODE_URL)/xenlight.a
+
+.PHONY: distclean
+distclean: clean
+
+-include $(DEPS)
diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
new file mode 100644
index 00

[Xen-devel] [PATCH v4 02/14] golang/xenlight: Add error constants and standard handling

2017-03-16 Thread Ronald Rojas
Create error type Errorxl for throwing proper xenlight
errors.

Update Ctx functions to throw Errorxl errors.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 78 ++-
 1 file changed, 76 insertions(+), 2 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index b025961..a99d9d3 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -37,8 +37,71 @@ import (
 )
 
 /*
+ * Errors
+ */
+
+type Error int
+
+const (
+   ErrorNonspecific  = Error(-C.ERROR_NONSPECIFIC)
+   ErrorVersion  = Error(-C.ERROR_VERSION)
+   ErrorFail = Error(-C.ERROR_FAIL)
+   ErrorNi   = Error(-C.ERROR_NI)
+   ErrorNomem= Error(-C.ERROR_NOMEM)
+   ErrorInval= Error(-C.ERROR_INVAL)
+   ErrorBadfail  = Error(-C.ERROR_BADFAIL)
+   ErrorGuestTimedout= Error(-C.ERROR_GUEST_TIMEDOUT)
+   ErrorTimedout = Error(-C.ERROR_TIMEDOUT)
+   ErrorNoparavirt   = Error(-C.ERROR_NOPARAVIRT)
+   ErrorNotReady = Error(-C.ERROR_NOT_READY)
+   ErrorOseventRegFail   = Error(-C.ERROR_OSEVENT_REG_FAIL)
+   ErrorBufferfull   = Error(-C.ERROR_BUFFERFULL)
+   ErrorUnknownChild = Error(-C.ERROR_UNKNOWN_CHILD)
+   ErrorLockFail = Error(-C.ERROR_LOCK_FAIL)
+   ErrorJsonConfigEmpty  = Error(-C.ERROR_JSON_CONFIG_EMPTY)
+   ErrorDeviceExists = Error(-C.ERROR_DEVICE_EXISTS)
+   ErrorCheckpointDevopsDoesNotMatch = 
Error(-C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
+   ErrorCheckpointDeviceNotSupported = 
Error(-C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
+   ErrorVnumaConfigInvalid   = Error(-C.ERROR_VNUMA_CONFIG_INVALID)
+   ErrorDomainNotfound   = Error(-C.ERROR_DOMAIN_NOTFOUND)
+   ErrorAborted  = Error(-C.ERROR_ABORTED)
+   ErrorNotfound = Error(-C.ERROR_NOTFOUND)
+   ErrorDomainDestroyed  = Error(-C.ERROR_DOMAIN_DESTROYED)
+   ErrorFeatureRemoved   = Error(-C.ERROR_FEATURE_REMOVED)
+)
+
+var errors = [...]string{
+   ErrorNonspecific:  "Non-specific error",
+   ErrorVersion:  "Wrong version",
+   ErrorFail: "Failed",
+   ErrorNi:   "Not Implemented",
+   ErrorNomem:"No memory",
+   ErrorInval:"Invalid argument",
+   ErrorBadfail:  "Bad Fail",
+   ErrorGuestTimedout:"Guest timed out",
+   ErrorTimedout: "Timed out",
+   ErrorNoparavirt:   "No Paravirtualization",
+   ErrorNotReady: "Not ready",
+   ErrorOseventRegFail:   "OS event registration failed",
+   ErrorBufferfull:   "Buffer full",
+   ErrorUnknownChild: "Unknown child",
+   ErrorLockFail: "Lock failed",
+   ErrorJsonConfigEmpty:  "JSON config empty",
+   ErrorDeviceExists: "Device exists",
+   ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does not match",
+   ErrorCheckpointDeviceNotSupported: "Checkpoint device not supported",
+   ErrorVnumaConfigInvalid:   "VNUMA config invalid",
+   ErrorDomainNotfound:   "Domain not found",
+   ErrorAborted:  "Aborted",
+   ErrorNotfound: "Not found",
+   ErrorDomainDestroyed:  "Domain destroyed",
+   ErrorFeatureRemoved:   "Feature removed",
+}
+
+/*
  * Types: Builtins
  */
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -50,6 +113,17 @@ var Ctx Context
 
 var logger *C.xentoollog_logger_stdiostream
 
+func (e Error) Error() string {
+   if 0 < int(e) && int(e) < len(errors) {
+   s := errors[e]
+   if s != "" {
+   return s
+   }
+   }
+   return fmt.Sprintf("libxl error: %d", -e)
+
+}
+
 func (Ctx *Context) IsOpen() bool {
return Ctx.ctx != nil
 }
@@ -64,7 +138,7 @@ func (Ctx *Context) Open() (err error) {
0, unsafe.Pointer(log

[Xen-devel] [PATCH RFC v3 7/8] golang/xenlight: Implement libxl_scheduler enumeration

2017-03-09 Thread Ronald Rojas
Include both constants and a Stringification for libxl_scheduler.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 62 +++
 1 file changed, 62 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index eb2b3cf..d4a6bc1 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -311,6 +311,68 @@ func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
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, )
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   *s = Scheduler(cs)
+   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, )
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   s = Scheduler(cs)
+
+   return
+}
+
 /*
  * Bitmap operations
  */
-- 
2.7.3


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


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

2017-03-09 Thread Ronald Rojas
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

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
 tools/golang/xenlight/xenlight.go | 238 ++
 1 file changed, 238 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index d4a6bc1..853a634 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -373,6 +373,244 @@ func SchedulerFromString(name string) (s Scheduler, err 
error) {
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
+   PoolNamestring
+   Scheduler   Scheduler
+   DomainCount int
+   Cpumap  Bitmap
+}
+
+func (cci C.libxl_cpupoolinfo)CToGo ()(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 = cci.cpumap.CToGo()
+
+   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, )
+
+   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 := cpupoolListSlice[i].CToGo()
+
+   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, _cpupool, C.uint32_t(Poolid))
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+   defer C.libxl_cpupoolinfo_dispose(_cpupool)
+
+   pool = c_cpupool.CToGo()
+
+   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()
+
+   cbm := Cpumap.GoToC()
+   defer C.libxl_bitmap_dispose()
+
+   ret := C.libxl_cpupool_create(Ctx.ctx, name, 
C.libxl_scheduler(Scheduler),
+   cbm, , )
+   if ret != 0 {
+   err = Error(-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 = Error(-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 = Error(-ret)
+   return
+   }
+
+   return
+}
+
+// int libxl_cpupool_cpuadd_cpumap

[Xen-devel] [PATCH RFC v3 6/8] golang/xenlight: Implement libxl_bitmap and helper operations

2017-03-09 Thread Ronald Rojas
Implement Bitmap type, along with helper functions.

The Bitmap type is implemented interllay in a way which makes it
easy to copy into and out of the C libxl_bitmap type.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>

---

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com

---
---
 tools/golang/xenlight/xenlight.go | 167 ++
 1 file changed, 167 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 34c3050..eb2b3cf 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -129,6 +129,20 @@ func (chwcap C.libxl_hwcap) toGo() (ghwcap Hwcap) {
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
  *
@@ -298,6 +312,159 @@ func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
 }
 
 /*
+ * Bitmap operations
+ */
+
+// Return a Go bitmap which is a copy of the referred C bitmap.
+func (cbm C.libxl_bitmap) toGo() (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 (gbm Bitmap) toC() (cbm C.libxl_bitmap) {
+   C.libxl_bitmap_init()
+
+   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-x-x -> 2,4-8,10
+   /// --x-xxx -> 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 {
+   //

[Xen-devel] [PATCH RFC v3 2/8] golang/xenlight: Add error constants and standard handling

2017-03-09 Thread Ronald Rojas
Create error type Errorxl for throwing proper xenlight
errors.

Update Ctx functions to throw Errorxl errors.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 78 ++-
 1 file changed, 76 insertions(+), 2 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index b025961..a99d9d3 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -37,8 +37,71 @@ import (
 )
 
 /*
+ * Errors
+ */
+
+type Error int
+
+const (
+   ErrorNonspecific  = Error(-C.ERROR_NONSPECIFIC)
+   ErrorVersion  = Error(-C.ERROR_VERSION)
+   ErrorFail = Error(-C.ERROR_FAIL)
+   ErrorNi   = Error(-C.ERROR_NI)
+   ErrorNomem= Error(-C.ERROR_NOMEM)
+   ErrorInval= Error(-C.ERROR_INVAL)
+   ErrorBadfail  = Error(-C.ERROR_BADFAIL)
+   ErrorGuestTimedout= Error(-C.ERROR_GUEST_TIMEDOUT)
+   ErrorTimedout = Error(-C.ERROR_TIMEDOUT)
+   ErrorNoparavirt   = Error(-C.ERROR_NOPARAVIRT)
+   ErrorNotReady = Error(-C.ERROR_NOT_READY)
+   ErrorOseventRegFail   = Error(-C.ERROR_OSEVENT_REG_FAIL)
+   ErrorBufferfull   = Error(-C.ERROR_BUFFERFULL)
+   ErrorUnknownChild = Error(-C.ERROR_UNKNOWN_CHILD)
+   ErrorLockFail = Error(-C.ERROR_LOCK_FAIL)
+   ErrorJsonConfigEmpty  = Error(-C.ERROR_JSON_CONFIG_EMPTY)
+   ErrorDeviceExists = Error(-C.ERROR_DEVICE_EXISTS)
+   ErrorCheckpointDevopsDoesNotMatch = 
Error(-C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
+   ErrorCheckpointDeviceNotSupported = 
Error(-C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
+   ErrorVnumaConfigInvalid   = Error(-C.ERROR_VNUMA_CONFIG_INVALID)
+   ErrorDomainNotfound   = Error(-C.ERROR_DOMAIN_NOTFOUND)
+   ErrorAborted  = Error(-C.ERROR_ABORTED)
+   ErrorNotfound = Error(-C.ERROR_NOTFOUND)
+   ErrorDomainDestroyed  = Error(-C.ERROR_DOMAIN_DESTROYED)
+   ErrorFeatureRemoved   = Error(-C.ERROR_FEATURE_REMOVED)
+)
+
+var errors = [...]string{
+   ErrorNonspecific:  "Non-specific error",
+   ErrorVersion:  "Wrong version",
+   ErrorFail: "Failed",
+   ErrorNi:   "Not Implemented",
+   ErrorNomem:"No memory",
+   ErrorInval:"Invalid argument",
+   ErrorBadfail:  "Bad Fail",
+   ErrorGuestTimedout:"Guest timed out",
+   ErrorTimedout: "Timed out",
+   ErrorNoparavirt:   "No Paravirtualization",
+   ErrorNotReady: "Not ready",
+   ErrorOseventRegFail:   "OS event registration failed",
+   ErrorBufferfull:   "Buffer full",
+   ErrorUnknownChild: "Unknown child",
+   ErrorLockFail: "Lock failed",
+   ErrorJsonConfigEmpty:  "JSON config empty",
+   ErrorDeviceExists: "Device exists",
+   ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does not match",
+   ErrorCheckpointDeviceNotSupported: "Checkpoint device not supported",
+   ErrorVnumaConfigInvalid:   "VNUMA config invalid",
+   ErrorDomainNotfound:   "Domain not found",
+   ErrorAborted:  "Aborted",
+   ErrorNotfound: "Not found",
+   ErrorDomainDestroyed:  "Domain destroyed",
+   ErrorFeatureRemoved:   "Feature removed",
+}
+
+/*
  * Types: Builtins
  */
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -50,6 +113,17 @@ var Ctx Context
 
 var logger *C.xentoollog_logger_stdiostream
 
+func (e Error) Error() string {
+   if 0 < int(e) && int(e) < len(errors) {
+   s := errors[e]
+   if s != "" {
+   return s
+   }
+   }
+   return fmt.Sprintf("libxl error: %d", -e)
+
+}
+
 func (Ctx *Context) IsOpen() bool {
return Ctx.ctx != nil
 }
@@ -64,7 +138,7 @@ func (Ctx *Context) Open() (err error) {
0, unsafe.Pointer(log

[Xen-devel] [PATCH RFC v3 5/8] golang/xenlight: Add tests host related functionality functions

2017-03-09 Thread Ronald Rojas
Create tests for the following functions:
- GetVersionInfo
- GetPhysinfo
- GetDominfo
- GetMaxCpus
- GetOnlineCpus
- GetMaxNodes
- GetFreeMemory

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
Signed-off-by: George Dunlap <george.dun...@citrix.com>

---
changes since last version

- created CFLAGS and LDLIBS variables to build test C
files with required dependencies.

- created create_context and destroy_context function
for tests to create/destroy libxl_ctx and xenlogger

- Formating changes

- Removed stale comments

- Removed redundant error checks in Golang tests

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/test/xeninfo/Makefile   | 41 +++
 tools/golang/xenlight/test/xeninfo/dominfo.c  | 33 ++
 tools/golang/xenlight/test/xeninfo/dominfo.go | 31 +
 tools/golang/xenlight/test/xeninfo/freememory.c   | 26 ++
 tools/golang/xenlight/test/xeninfo/freememory.go  | 25 ++
 tools/golang/xenlight/test/xeninfo/maxcpu.c   | 18 ++
 tools/golang/xenlight/test/xeninfo/maxcpu.go  | 24 +
 tools/golang/xenlight/test/xeninfo/maxnodes.c | 15 +
 tools/golang/xenlight/test/xeninfo/maxnodes.go| 24 +
 tools/golang/xenlight/test/xeninfo/onlinecpu.c| 18 ++
 tools/golang/xenlight/test/xeninfo/onlinecpu.go   | 24 +
 tools/golang/xenlight/test/xeninfo/physinfo.c | 32 ++
 tools/golang/xenlight/test/xeninfo/physinfo.go| 32 ++
 tools/golang/xenlight/test/xeninfo/print.h| 22 
 tools/golang/xenlight/test/xeninfo/versioninfo.c  | 22 
 tools/golang/xenlight/test/xeninfo/versioninfo.go | 28 
 tools/golang/xenlight/test/xeninfo/xenlight.go|  1 +
 17 files changed, 416 insertions(+)
 create mode 100644 tools/golang/xenlight/test/xeninfo/Makefile
 create mode 100644 tools/golang/xenlight/test/xeninfo/dominfo.c
 create mode 100644 tools/golang/xenlight/test/xeninfo/dominfo.go
 create mode 100644 tools/golang/xenlight/test/xeninfo/freememory.c
 create mode 100644 tools/golang/xenlight/test/xeninfo/freememory.go
 create mode 100644 tools/golang/xenlight/test/xeninfo/maxcpu.c
 create mode 100644 tools/golang/xenlight/test/xeninfo/maxcpu.go
 create mode 100644 tools/golang/xenlight/test/xeninfo/maxnodes.c
 create mode 100644 tools/golang/xenlight/test/xeninfo/maxnodes.go
 create mode 100644 tools/golang/xenlight/test/xeninfo/onlinecpu.c
 create mode 100644 tools/golang/xenlight/test/xeninfo/onlinecpu.go
 create mode 100644 tools/golang/xenlight/test/xeninfo/physinfo.c
 create mode 100644 tools/golang/xenlight/test/xeninfo/physinfo.go
 create mode 100644 tools/golang/xenlight/test/xeninfo/print.h
 create mode 100644 tools/golang/xenlight/test/xeninfo/versioninfo.c
 create mode 100644 tools/golang/xenlight/test/xeninfo/versioninfo.go
 create mode 12 tools/golang/xenlight/test/xeninfo/xenlight.go

diff --git a/tools/golang/xenlight/test/xeninfo/Makefile 
b/tools/golang/xenlight/test/xeninfo/Makefile
new file mode 100644
index 000..aae5544
--- /dev/null
+++ b/tools/golang/xenlight/test/xeninfo/Makefile
@@ -0,0 +1,41 @@
+XEN_ROOT = $(CURDIR)/../../../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+GO ?= go
+
+TESTS = dominfo freememory maxcpu onlinecpu physinfo versioninfo
+CBINARIES = $(TESTS:%=%-c)
+GOBINARIES = $(TESTS:%=%-go)
+
+CFLAGS += -Werror
+CFLAGS += $(CFLAGS_libxentoollog)
+CFLAGS += $(CFLAGS_libxenlight)
+
+LDLIBS += $(LDLIBS_libxentoollog)
+LDLIBS += $(LDLIBS_libxenlight)
+
+all: build
+
+test: clean build
+   for test in $(TESTS) ; do \
+   ./$$test-c >> c.output ; \
+   ./$$test-go >> go.output ; \
+   if cmp -s "c.output" "go.output"; then\
+   echo "$$test PASSED";\
+   else \
+   echo "$$test FAILED";\
+   fi ; \
+   done
+
+build: $(CBINARIES) $(GOBINARIES)
+
+%-c: %.c
+   gcc $(CFLAGS) -o $@ $< $(LDLIBS)
+
+%-go: %.go
+   GOPATH=$(XEN_ROOT)/tools/golang $(GO) build -o $@ $<
+
+clean:
+   rm -f *-c
+   rm -f *-go
+   rm -f *.output
diff --git a/tools/golang/xenlight/test/xeninfo/dominfo.c 
b/tools/golang/xenlight/test/xeninfo/dominfo.c
new file mode 100644
index 000..2c63583
--- /dev/null
+++ b/tools/golang/xenlight/test/xeninfo/dominfo.c
@@ -0,0 +1,33 @@
+#include 
+#include 
+#include 
+#include "print.h"
+
+int main(void){
+
+libxl_ctx *context;
+libxl_dominfo info;
+int err;
+long cpu_time;
+context = create_context();
+libxl_dominfo_init();
+err = libxl_domain_info(context, , 0);
+if (err != 0)
+return err;
+
+printf("%d\n%d\n", info.domid, info.ssidref);
+printf("%s\n%s\n%s\n%s\n%s\n

[Xen-devel] [PATCH RFC v3 1/8] golang/xenlight: Create stub package

2017-03-09 Thread Ronald Rojas
Create a basic Makefile to build and install libxenlight Golang
bindings. Also add a stub package which only opens libxl context.

Include a global xenlight.Ctx variable which can be used as the
default context by the entire program if desired.

For now, return simple errors. Proper error handling will be
added in next patch.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
Signed-off-by: George Dunlap <george.dun...@citrix.com>
---

Changes:

- Added global logger variable and destroyed the logger instance
when closing the context.

- Whitespace fixes

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/Makefile|  1 +
 tools/Rules.mk|  7 
 tools/golang/Makefile | 27 
 tools/golang/xenlight/Makefile| 49 ++
 tools/golang/xenlight/xenlight.go | 88 +++
 5 files changed, 172 insertions(+)
 create mode 100644 tools/golang/Makefile
 create mode 100644 tools/golang/xenlight/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 77e0723..caa27f4 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -31,6 +31,7 @@ endif
 
 SUBDIRS-y += xenpmd
 SUBDIRS-y += libxl
+#SUBDIRS-$(CONFIG_GOLANG) += golang
 SUBDIRS-y += helpers
 SUBDIRS-$(CONFIG_X86) += xenpaging
 SUBDIRS-$(CONFIG_X86) += debugger/gdbsx
diff --git a/tools/Rules.mk b/tools/Rules.mk
index b35999b..b5b9ace 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -30,6 +30,13 @@ XENSTORE_XENSTORED ?= y
 debug ?= y
 debug_symbols ?= $(debug)
 
+# Uncomment to compile with Go
+CONFIG_GOLANG ?= y
+ifeq ($(CONFIG_GOLANG),y)
+XEN_GOPATH= $(XEN_ROOT)/tools/golang
+XEN_GOCODE_URL= golang.xenproject.org
+endif
+
 ifeq ($(debug_symbols),y)
 CFLAGS += -g3
 endif
diff --git a/tools/golang/Makefile b/tools/golang/Makefile
new file mode 100644
index 000..47a9235
--- /dev/null
+++ b/tools/golang/Makefile
@@ -0,0 +1,27 @@
+XEN_ROOT=$(CURDIR)/../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+# In order to link against a package in Go, the package must live in a
+# directory tree in the way that Go expects.  To make this possible,
+# there must be a directory such that we can set GOPATH=${dir}, and
+# the package will be under $GOPATH/src/${full-package-path}.
+
+# So we set XEN_GOPATH to $XEN_ROOT/tools/golang.  The xenlight
+# "package build" directory ($PWD/xenlight) will create the "package
+# source" directory in the proper place.  Go programs can use this
+# package by setting GOPATH=$(XEN_GOPATH).
+
+SUBDIRS-y = xenlight
+
+.PHONY: build all
+all build: subdirs-all
+
+.PHONY: install
+install: subdirs-install
+
+.PHONY: clean
+clean: subdirs-clean
+   $(RM) -r src pkg
+
+.PHONY: distclean
+distclean: clean
diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
new file mode 100644
index 000..5db665d
--- /dev/null
+++ b/tools/golang/xenlight/Makefile
@@ -0,0 +1,49 @@
+XEN_ROOT=$(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+# Standing boldly against convention, we insist on installing the
+# package source under $(prefix)/share/gocode
+GOCODE_DIR ?= $(prefix)/share/gocode/
+GOXL_PKG_DIR = /src/$(XEN_GOCODE_URL)/xenlight/
+GOXL_INSTALL_DIR = $(GOCODE_DIR)$(GOXL_PKG_DIR)
+
+# PKGSOURCES: Files which comprise the distributed source package
+PKGSOURCES = xenlight.go
+
+GO ?= go
+
+.PHONY: all
+all: build
+
+.PHONY: package
+package: $(XEN_GOPATH)$(GOXL_PKG_DIR)$(PKGSOURCES)
+
+$(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/$(PKGSOURCES): $(PKGSOURCES)
+   $(INSTALL_DIR) $(XEN_GOPATH)$(GOXL_PKG_DIR)
+   $(INSTALL_DATA) $(PKGSOURCES) $(XEN_GOPATH)$(GOXL_PKG_DIR)
+
+# Go will do its own dependency checking, and not actuall go through
+# with the build if none of the input files have changed.
+#
+# NB that because the users of this library need to be able to
+# recompile the library from source, it needs to include '-lxenlight'
+# in the LDFLAGS; and thus we need to add -L$(XEN_XENLIGHT) here
+# so that it can find the actual library.
+.PHONY: build
+build: package
+   CGO_CFLAGS="$(CFLAGS_libxenlight) $(CFLAGS_libxentoollog)" 
CGO_LDFLAGS="$(LDLIBS_libxenlight) $(LDLIBS_libxentoollog)-L$(XEN_XENLIGHT) 
-L$(XEN_LIBXENTOOLLOG)" GOPATH=$(XEN_GOPATH) $(GO) install -x 
$(XEN_GOCODE_URL)/xenlight
+
+.PHONY: install
+install: build
+   $(INSTALL_DIR) $(DESTDIR)$(GOXL_INSTALL_DIR)
+   $(INSTALL_DATA) $(XEN_GOPATH)$(GOXL_PKG_DIR)$(PKGSOURCES) 
$(DESTDIR)$(GOXL_INSTALL_DIR)
+
+.PHONY: clean
+clean:
+   $(RM) -r $(XEN_GOPATH)$(GOXL_PKG_DIR)
+   $(RM) $(XEN_GOPATH)/pkg/*/$(XEN_GOCODE_URL)/xenlight.a
+
+.PHONY: distclean
+distclean: clean
+
+-include $(DEPS)
diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
new file mode 100644
index 000..b025961
--- /dev/null
+

[Xen-devel] [PATCH RFC v3 4/8] golang/xenlight: Implement libxl_domain_info and libxl_domain_unpause

2017-03-09 Thread Ronald Rojas
Add calls for the following host-related functionality:
- libxl_domain_info
- libxl_domain_unpause

Include Golang version for the libxl_domain_info as
DomainInfo.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
Changes since last version

- Formating fixes

- used defer for libxl_dominfo_dispose

- Removed unnessary unsafe.Pointer() casts.

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com

---
---
 tools/golang/xenlight/xenlight.go | 136 +-
 1 file changed, 133 insertions(+), 3 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 785eaaf..34c3050 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -33,6 +33,7 @@ import "C"
 
 import (
"fmt"
+   "time"
"unsafe"
 )
 
@@ -102,13 +103,19 @@ var errors = [...]string{
  * Types: Builtins
  */
 
+type Domid uint32
+
+type MemKB uint64
+
+type Uuid C.libxl_uuid
+
 type Context struct {
ctx *C.libxl_ctx
 }
 
 type Hwcap []C.uint32_t
 
-func (chwcap C.libxl_hwcap) CToGo() (ghwcap Hwcap) {
+func (chwcap C.libxl_hwcap) toGo() (ghwcap Hwcap) {
// Alloc a Go slice for the bytes
size := 8
ghwcap = make([]C.uint32_t, size)
@@ -161,7 +168,7 @@ func (cphys *C.libxl_physinfo) toGo() (physinfo *Physinfo) {
physinfo.SharingFreedPages = uint64(cphys.sharing_freed_pages)
physinfo.SharingUsedFrames = uint64(cphys.sharing_used_frames)
physinfo.NrNodes = uint32(cphys.nr_nodes)
-   physinfo.HwCap = cphys.hw_cap.CToGo()
+   physinfo.HwCap = cphys.hw_cap.toGo()
physinfo.CapHvm = bool(cphys.cap_hvm)
physinfo.CapHvmDirectio = bool(cphys.cap_hvm_directio)
 
@@ -203,6 +210,93 @@ func (cinfo *C.libxl_version_info) toGo() (info 
*VersionInfo) {
return
 }
 
+type ShutdownReason int32
+
+const (
+   ShutdownReasonUnknown   = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_UNKNOWN)
+   ShutdownReasonPoweroff  = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_POWEROFF)
+   ShutdownReasonReboot= ShutdownReason(C.LIBXL_SHUTDOWN_REASON_REBOOT)
+   ShutdownReasonSuspend   = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SUSPEND)
+   ShutdownReasonCrash = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_CRASH)
+   ShutdownReasonWatchdog  = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_WATCHDOG)
+   ShutdownReasonSoftReset = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SOFT_RESET)
+)
+
+func (sr ShutdownReason) String() (str string) {
+   cstr := C.libxl_shutdown_reason_to_string(C.libxl_shutdown_reason(sr))
+   str = C.GoString(cstr)
+
+   return
+}
+
+type DomainType int32
+
+const (
+   DomainTypeInvalid = DomainType(C.LIBXL_DOMAIN_TYPE_INVALID)
+   DomainTypeHvm = DomainType(C.LIBXL_DOMAIN_TYPE_HVM)
+   DomainTypePv  = DomainType(C.LIBXL_DOMAIN_TYPE_PV)
+)
+
+func (dt DomainType) String() (str string) {
+   cstr := C.libxl_domain_type_to_string(C.libxl_domain_type(dt))
+   str = C.GoString(cstr)
+
+   return
+}
+
+type Dominfo struct {
+   Uuid  Uuid
+   Domid Domid
+   Ssidref   uint32
+   SsidLabel string
+   Running   bool
+   Blocked   bool
+   Pausedbool
+   Shutdown  bool
+   Dying bool
+   NeverStop bool
+
+   ShutdownReason   int32
+   OutstandingMemkb MemKB
+   CurrentMemkb MemKB
+   SharedMemkb  MemKB
+   PagedMemkb   MemKB
+   MaxMemkb MemKB
+   CpuTime  time.Duration
+   VcpuMaxIduint32
+   VcpuOnline   uint32
+   Cpupool  uint32
+   DomainType   int32
+}
+
+func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
+
+   di = {}
+   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
+}
+
 /*
  * Context
  */
@@ -332,6 +426,7 @@ func (Ctx *Context) GetPhysinfo() (physinfo *Physinfo, err 
error) {
}
var 

Re: [Xen-devel] [PATCH v2 4/5] golang/xenlight: Implement libxl_domain_info and libxl_domain_unpause

2017-03-03 Thread Ronald Rojas
On Fri, Mar 03, 2017 at 03:15:51PM +, George Dunlap wrote:
> On 02/03/17 16:07, Ronald Rojas wrote:
> > Add calls for the following host-related functionality:
> > - libxl_domain_info
> > - libxl_domain_unpause
> > 
> > Include Golang version for the libxl_domain_info as
> > DomainInfo.
> > 
> > Signed-off-by: George Dunlap <george.dun...@citrix.com>
> > Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
> > ---
> > Changes since last version
> > - Created type and enumeration of DomainType and ShutdownReason
> > 
> > - Created String() method for DomainType and ShutdownReason
> > 
> > - Refactored creating DomainInfo from c type into seperate
> > toGo() function
> > 
> > - Applied libxl_domain_info_init/dispose()
> > 
> > - whitespace fixes
> > 
> > CC: xen-devel@lists.xen.org
> > CC: george.dun...@citrix.com
> > CC: ian.jack...@eu.citrix.com
> > CC: wei.l...@citrix.com
> > 
> > ---
> > ---
> >  tools/golang/xenlight/xenlight.go | 132 
> > ++
> >  1 file changed, 132 insertions(+)
> > 
> > diff --git a/tools/golang/xenlight/xenlight.go 
> > b/tools/golang/xenlight/xenlight.go
> > index 63cc805..18dedcb 100644
> > --- a/tools/golang/xenlight/xenlight.go
> > +++ b/tools/golang/xenlight/xenlight.go
> > @@ -34,6 +34,7 @@ import "C"
> >  import (
> > "fmt"
> > "unsafe"
> > +   "time"
> >  )
> >  
> >  /*
> > @@ -102,6 +103,12 @@ var errors = [...]string{
> >   * Types: Builtins
> >   */
> >  
> > +type Domid uint32
> > +
> > +type MemKB uint64
> > +
> > +type Uuid C.libxl_uuid
> > +
> >  type Context struct {
> > ctx *C.libxl_ctx
> >  }
> > @@ -203,6 +210,95 @@ func (cinfo *C.libxl_version_info) toGo() (info 
> > *VersionInfo) {
> > return
> >  }
> >  
> > +type ShutdownReason int32
> > +
> > +const(
> > +   ShutdownReasonUnknown = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_UNKNOWN)
> > +   ShutdownReasonPoweroff = 
> > ShutdownReason(C.LIBXL_SHUTDOWN_REASON_POWEROFF)
> > +   ShutdownReasonReboot = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_REBOOT)
> > +   ShutdownReasonSuspend = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SUSPEND)
> > +   ShutdownReasonCrash = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_CRASH)
> > +   ShutdownReasonWatchdog = 
> > ShutdownReason(C.LIBXL_SHUTDOWN_REASON_WATCHDOG)
> > +   ShutdownReasonSoftReset = 
> > ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SOFT_RESET)
> 
> Looks like this could use having `go fmt` run.
> 
> > +
> > +)
> > +
> > +func (sr ShutdownReason) String()(str string){
> > +   cstr := C.libxl_shutdown_reason_to_string(C.libxl_shutdown_reason(sr))
> > +   str = C.GoString(cstr)
> > +
> > +   return
> > +}
> > +
> > +type DomainType int32
> > +
> > +const(
> > +   DomainTypeInvalid = DomainType(C.LIBXL_DOMAIN_TYPE_INVALID)
> > +   DomainTypeHvm = DomainType(C.LIBXL_DOMAIN_TYPE_HVM)
> > +   DomainTypePv = DomainType(C.LIBXL_DOMAIN_TYPE_PV)
> > +)
> > +
> > +func (dt DomainType) String()(str string){
> > +   cstr := C.libxl_domain_type_to_string(C.libxl_domain_type(dt))
> > +   str = C.GoString(cstr)
> > +
> > +   return
> > +}
> > +
> > +type Dominfo struct {
> > +   Uuid   Uuid
> > +   Domid  Domid
> > +   Ssidref uint32
> > +   SsidLabel string
> > +   Runningbool
> > +   Blockedbool
> > +   Paused bool
> > +   Shutdown   bool
> > +   Dying  bool
> > +   NeverStop bool
> > +
> > +   ShutdownReason   int32
> > +   OutstandingMemkb MemKB
> > +   CurrentMemkb MemKB
> > +   SharedMemkb  MemKB
> > +   PagedMemkb   MemKB
> > +   MaxMemkb MemKB
> > +   CpuTime  time.Duration
> > +   VcpuMaxId   uint32
> > +   VcpuOnline   uint32
> > +   Cpupool   uint32
> > +   DomainType   int32
> > +
> > +}
> > +
> > +func (cdi *C.libxl_dominfo) toGo()(di *Dominfo){
> > +
> > +   di = {}
> > +   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.shutdow

Re: [Xen-devel] [PATCH v2 3/5] golang/xenlight: Add host-related functionality

2017-03-03 Thread Ronald Rojas
On Fri, Mar 03, 2017 at 02:54:56PM +, George Dunlap wrote:
> On 02/03/17 16:07, Ronald Rojas wrote:
> > Add calls for the following host-related functionality:
> > - libxl_get_max_cpus
> > - libxl_get_online_cpus
> > - libxl_get_max_nodes
> > - libxl_get_free_memory
> > - libxl_get_physinfo
> > - libxl_get_version_info
> > 
> > Include Golang versions of the following structs:
> > - libxl_physinfo as Physinfo
> > - libxl_version_info as VersionInfo
> > - libxl_hwcap as Hwcap
> > 
> > Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
> 
> Looks good -- just two minor comments...
> 
> > ---
> > Changes since last version
> > 
> > - Refactored creating Physinfo and VersionInfo types into
> > seperate toGo() functions.
> > 
> > - Used libxl__init() and libxl__dispose() on IDL
> > type physinfo
> > 
> > - Whitespace fixes
> > 
> > CC: xen-devel@lists.xen.org
> > CC: george.dun...@citrix.com
> > CC: ian.jack...@eu.citrix.com
> > CC: wei.l...@citrix.com
> > ---
> > ---
> >  tools/golang/xenlight/xenlight.go | 200 
> > ++
> >  1 file changed, 200 insertions(+)
> > 
> > diff --git a/tools/golang/xenlight/xenlight.go 
> > b/tools/golang/xenlight/xenlight.go
> > index cbd3527..63cc805 100644
> > --- a/tools/golang/xenlight/xenlight.go
> > +++ b/tools/golang/xenlight/xenlight.go
> > @@ -106,6 +106,103 @@ type Context struct {
> > ctx *C.libxl_ctx
> >  }
> >  
> > +type Hwcap []C.uint32_t
> > +
> > +func (chwcap C.libxl_hwcap) CToGo() (ghwcap Hwcap) {
> 
> Was there a reason you left this as CToGo() rather than just toGo()?
> 

No. This should be changed to toGo()

[snip]

> > +//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
> > +   C.libxl_physinfo_init()
> > +
> > +   ret := C.libxl_get_physinfo(Ctx.ctx, )
> > +
> > +   if ret < 0 {
> > +   err = Error(ret)
> > +   return
> > +   }
> > +   physinfo = cphys.toGo()
> > +   C.libxl_physinfo_dispose()
> 
> I think it would probably be more idiomatic to write "defer
> C.libxl_physinfo_dispose()" just after the physinfo_init.
> 
> If the init() actually allocated any memory, the current code would
> return without disposing of it if there was an error.  `defer` avoids
> that by ensuring that *all* return paths call the clean-up function.

Yep. Using defer is the better approach here. I will change
it in all instances where I use the init/dispose functions.

> 
> Other than that, looks great, thanks!
> 
>  -George
> 

Thanks,
Ronald

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


Re: [Xen-devel] [PATCH v2 5/5] golang/xenlight: Add tests host related functionality functions

2017-03-02 Thread Ronald Rojas
On Thu, Mar 02, 2017 at 05:53:00PM +, George Dunlap wrote:
> On 02/03/17 17:36, Ian Jackson wrote:
> > Ronald Rojas writes ("[PATCH v2 5/5] golang/xenlight: Add tests host 
> > related functionality functions"):
> >> Create tests for the following functions:
> >> - GetVersionInfo
> >> - GetPhysinfo
> >> - GetDominfo
> >> - GetMaxCpus
> >> - GetOnlineCpus
> >> - GetMaxNodes
> >> - GetFreeMemory
> > 
> > I assume this whole series is RFC still ?
> 
> I think the earlier patches looked pretty close to being checked in.  I
> think having a basic chunk of functionality checked in will make it
> easier to actually collaborate on improving things.
> 
> > I don't feel competent to review the golang code.  But I did spot some
> > C to review :-)
> > 
> >> diff --git a/tools/golang/xenlight/test/xeninfo/freememory.c 
> >> b/tools/golang/xenlight/test/xeninfo/freememory.c
> >> new file mode 100644
> >> index 000..04ee90d
> >> --- /dev/null
> >> +++ b/tools/golang/xenlight/test/xeninfo/freememory.c
> >> @@ -0,0 +1,24 @@
> >> +#include 
> >> +#include 
> >> +#include 
> >> +#include "print.h"
> >> +
> >> +int main(){
> > 
> > This is an unusual definition of main.  (I think it's still legal, but
> > probably not what you meant.)
> > 

I did this because I'm not expecting any arguments  to be passed into
main. I can change it to the standard definition instead.

> >> +libxl_ctx *context;
> >> +libxl_ctx_alloc(,LIBXL_VERSION, 0, NULL);
> >> +
> >> +uint64_t free_memory;
> >> +int err = libxl_get_free_memory(context, _memory);
> >> +if (err < 0)
> >> +{
> >> +printf("%d\n", err);
> >> +}
> >> +else
> >> +{
> >> +printf("%lu\n", free_memory);
> >> +}
> > 
> > This output is ambiguous.
> > 
> >> +libxl_ctx_free(context);
> >> +
> >> +}
> > 
> > Returns from main without returning a value.  Error code is lost.
> 
> He's not testing whether the call succeeds; he's testing if the call has
> the same result as the golang function.
> 
> But this won't quite work anymore, because as of v2 the golang return
> values are positive constants (to make it easy to use them for indexes).
>  So if there were an identical error, the output would be different even
> if the error number were identical.

You are right. I need to negate the value that I print in the go file.

> 
> That needs to be fixed; but I also agree it would probably be better to
> print something that distinguishes between success and failure.

I think it's always clear whether the function failed or succeeded. The
error code will always be a negative number while free_memory can only
be non-negative because it is an unsigned long. There is no overlap
between those two values.


Ronald

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


[Xen-devel] [PATCH v2 4/5] golang/xenlight: Implement libxl_domain_info and libxl_domain_unpause

2017-03-02 Thread Ronald Rojas
Add calls for the following host-related functionality:
- libxl_domain_info
- libxl_domain_unpause

Include Golang version for the libxl_domain_info as
DomainInfo.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
Changes since last version
- Created type and enumeration of DomainType and ShutdownReason

- Created String() method for DomainType and ShutdownReason

- Refactored creating DomainInfo from c type into seperate
toGo() function

- Applied libxl_domain_info_init/dispose()

- whitespace fixes

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com

---
---
 tools/golang/xenlight/xenlight.go | 132 ++
 1 file changed, 132 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 63cc805..18dedcb 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -34,6 +34,7 @@ import "C"
 import (
"fmt"
"unsafe"
+   "time"
 )
 
 /*
@@ -102,6 +103,12 @@ var errors = [...]string{
  * Types: Builtins
  */
 
+type Domid uint32
+
+type MemKB uint64
+
+type Uuid C.libxl_uuid
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -203,6 +210,95 @@ func (cinfo *C.libxl_version_info) toGo() (info 
*VersionInfo) {
return
 }
 
+type ShutdownReason int32
+
+const(
+   ShutdownReasonUnknown = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_UNKNOWN)
+   ShutdownReasonPoweroff = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_POWEROFF)
+   ShutdownReasonReboot = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_REBOOT)
+   ShutdownReasonSuspend = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SUSPEND)
+   ShutdownReasonCrash = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_CRASH)
+   ShutdownReasonWatchdog = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_WATCHDOG)
+   ShutdownReasonSoftReset = 
ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SOFT_RESET)
+
+)
+
+func (sr ShutdownReason) String()(str string){
+   cstr := C.libxl_shutdown_reason_to_string(C.libxl_shutdown_reason(sr))
+   str = C.GoString(cstr)
+
+   return
+}
+
+type DomainType int32
+
+const(
+   DomainTypeInvalid = DomainType(C.LIBXL_DOMAIN_TYPE_INVALID)
+   DomainTypeHvm = DomainType(C.LIBXL_DOMAIN_TYPE_HVM)
+   DomainTypePv = DomainType(C.LIBXL_DOMAIN_TYPE_PV)
+)
+
+func (dt DomainType) String()(str string){
+   cstr := C.libxl_domain_type_to_string(C.libxl_domain_type(dt))
+   str = C.GoString(cstr)
+
+   return
+}
+
+type Dominfo struct {
+   Uuid   Uuid
+   Domid  Domid
+   Ssidref uint32
+   SsidLabel string
+   Runningbool
+   Blockedbool
+   Paused bool
+   Shutdown   bool
+   Dying  bool
+   NeverStop bool
+
+   ShutdownReason   int32
+   OutstandingMemkb MemKB
+   CurrentMemkb MemKB
+   SharedMemkb  MemKB
+   PagedMemkb   MemKB
+   MaxMemkb MemKB
+   CpuTime  time.Duration
+   VcpuMaxId   uint32
+   VcpuOnline   uint32
+   Cpupool   uint32
+   DomainType   int32
+
+}
+
+func (cdi *C.libxl_dominfo) toGo()(di *Dominfo){
+
+   di = {}
+   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
+}
+
 /*
  * Context
  */
@@ -356,3 +452,39 @@ func (Ctx *Context) GetVersionInfo() (info *VersionInfo, 
err error) {
 
return
 }
+
+func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
+   return
+   }
+
+   var cdi C.libxl_dominfo
+   C.libxl_dominfo_init()
+
+   ret := C.libxl_domain_info(Ctx.ctx, unsafe.Pointer(), 
C.uint32_t(Id))
+
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   di = cdi.toGo()
+   C.libxl_dominfo_dispose()
+
+   return
+}
+
+func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
+   err = Ctx.CheckOpen()
+   if err != 

[Xen-devel] [PATCH v2 2/5] golang/xenlight: Add error constants and standard handling

2017-03-02 Thread Ronald Rojas
Create error type Errorxl for throwing proper xenlight
errors.

Update Ctx functions to throw Errorxl errors.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
Changes since last patch:

- Whitespace fixes

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/golang/xenlight/xenlight.go | 81 +--
 1 file changed, 77 insertions(+), 4 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 0a0cea2..cbd3527 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -29,17 +29,79 @@ import "C"
  *
  * To get back to static linking:
  * #cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
-lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall -lz 
-luuid -lutil
-*/
+ */
 
 import (
"fmt"
"unsafe"
 )
 
+/*
+ * Errors
+ */
+
+type Error int
+
+const (
+   ErrorNonspecific  = Error(-C.ERROR_NONSPECIFIC)
+   ErrorVersion  = Error(-C.ERROR_VERSION)
+   ErrorFail = Error(-C.ERROR_FAIL)
+   ErrorNi   = Error(-C.ERROR_NI)
+   ErrorNomem= Error(-C.ERROR_NOMEM)
+   ErrorInval= Error(-C.ERROR_INVAL)
+   ErrorBadfail  = Error(-C.ERROR_BADFAIL)
+   ErrorGuestTimedout= Error(-C.ERROR_GUEST_TIMEDOUT)
+   ErrorTimedout = Error(-C.ERROR_TIMEDOUT)
+   ErrorNoparavirt   = Error(-C.ERROR_NOPARAVIRT)
+   ErrorNotReady = Error(-C.ERROR_NOT_READY)
+   ErrorOseventRegFail   = Error(-C.ERROR_OSEVENT_REG_FAIL)
+   ErrorBufferfull   = Error(-C.ERROR_BUFFERFULL)
+   ErrorUnknownChild = Error(-C.ERROR_UNKNOWN_CHILD)
+   ErrorLockFail = Error(-C.ERROR_LOCK_FAIL)
+   ErrorJsonConfigEmpty  = Error(-C.ERROR_JSON_CONFIG_EMPTY)
+   ErrorDeviceExists = Error(-C.ERROR_DEVICE_EXISTS)
+   ErrorCheckpointDevopsDoesNotMatch = 
Error(-C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
+   ErrorCheckpointDeviceNotSupported = 
Error(-C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
+   ErrorVnumaConfigInvalid   = Error(-C.ERROR_VNUMA_CONFIG_INVALID)
+   ErrorDomainNotfound   = Error(-C.ERROR_DOMAIN_NOTFOUND)
+   ErrorAborted  = Error(-C.ERROR_ABORTED)
+   ErrorNotfound = Error(-C.ERROR_NOTFOUND)
+   ErrorDomainDestroyed  = Error(-C.ERROR_DOMAIN_DESTROYED)
+   ErrorFeatureRemoved   = Error(-C.ERROR_FEATURE_REMOVED)
+)
+
+var errors = [...]string{
+   ErrorNonspecific:  "Non-specific error",
+   ErrorVersion:  "Wrong version",
+   ErrorFail: "Failed",
+   ErrorNi:   "Not Implemented",
+   ErrorNomem:"No memory",
+   ErrorInval:"Invalid argument",
+   ErrorBadfail:  "Bad Fail",
+   ErrorGuestTimedout:"Guest timed out",
+   ErrorTimedout: "Timed out",
+   ErrorNoparavirt:   "No Paravirtualization",
+   ErrorNotReady: "Not ready",
+   ErrorOseventRegFail:   "OS event registration failed",
+   ErrorBufferfull:   "Buffer full",
+   ErrorUnknownChild: "Unknown child",
+   ErrorLockFail: "Lock failed",
+   ErrorJsonConfigEmpty:  "JSON config empty",
+   ErrorDeviceExists: "Device exists",
+   ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does not match",
+   ErrorCheckpointDeviceNotSupported: "Checkpoint device not supported",
+   ErrorVnumaConfigInvalid:   "VNUMA config invalid",
+   ErrorDomainNotfound:   "Domain not found",
+   ErrorAborted:  "Aborted",
+   ErrorNotfound: "Not found",
+   ErrorDomainDestroyed:  "Domain destroyed",
+   ErrorFeatureRemoved:   "Feature removed",
+}
 
 /*
  * Types: Builtins
  */
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -49,6 +111,17 @@ type Context struct {
  */
 var Ctx Context
 
+func (e Error) Error() string {
+   if 0 < int(e) && int(e) < len(errors) {
+   s := errors[e]
+

[Xen-devel] [PATCH v2 1/5] golang/xenlight: Create stub package

2017-03-02 Thread Ronald Rojas
Create a basic Makefile to build and install libxenlight Golang
bindings. Also add a stub package which only opens libxl context.

Include a global xenlight.Ctx variable which can be used as the
default context by the entire program if desired.

For now, return simple errors. Proper error handling will be
added in next patch.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
Signed-off-by: George Dunlap <george.dun...@citrix.com>
---

Changes:
- Changed GPL Lisense to LGPL Lisense

- Initialized xentoollog_logger for storing error messages

- Moved manual-enable config option to tools/Rules.mk, use
  CONFIG_GOLANG in tools/Makefile

- Added XEN_GOPATH, pointing to tools/golang

- Modified tools/golang/xenlight makefile to construct necessary $GOPATH

- Added tools/golang/Makefile, so we don't need special rules in tools
  to make tools/golang/xenlight; and so we have a single place to remove the
  $GOPATH build side-effects ($GOPATH/src and $GOPATH/pkg)

- Build of tools/golang/xenlight sets $GOPATH and does a 'go install'

- Use tree-provided CFLAGS_libxenlight and LDLIBS_libxenlight, rather
  than hard-coding our own

- Made a PKGSOURCES variable to track dependencies of all target files
  which need to be part of the output package (i.e., what's put in
  $GOPATH/src).  At the moment this is one file, but it will probably
  be more once we start using the IDL.

CC: xen-devel@lists.xen.org
CC: george.dun...@citrix.com
CC: ian.jack...@eu.citrix.com
CC: wei.l...@citrix.com
---
---
 tools/Makefile|  1 +
 tools/Rules.mk|  6 +++
 tools/golang/Makefile | 27 +
 tools/golang/xenlight/Makefile| 49 ++
 tools/golang/xenlight/xenlight.go | 85 +++
 5 files changed, 168 insertions(+)
 create mode 100644 tools/golang/Makefile
 create mode 100644 tools/golang/xenlight/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 77e0723..df1fda1 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -31,6 +31,7 @@ endif
 
 SUBDIRS-y += xenpmd
 SUBDIRS-y += libxl
+SUBDIRS-$(CONFIG_GOLANG) += golang
 SUBDIRS-y += helpers
 SUBDIRS-$(CONFIG_X86) += xenpaging
 SUBDIRS-$(CONFIG_X86) += debugger/gdbsx
diff --git a/tools/Rules.mk b/tools/Rules.mk
index b35999b..24e5220 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -30,6 +30,12 @@ XENSTORE_XENSTORED ?= y
 debug ?= y
 debug_symbols ?= $(debug)
 
+# Uncomment to compile with Go
+CONFIG_GOLANG ?= y
+ifeq ($(CONFIG_GOLANG),y)
+XEN_GOPATH= $(XEN_ROOT)/tools/golang
+endif
+
 ifeq ($(debug_symbols),y)
 CFLAGS += -g3
 endif
diff --git a/tools/golang/Makefile b/tools/golang/Makefile
new file mode 100644
index 000..47a9235
--- /dev/null
+++ b/tools/golang/Makefile
@@ -0,0 +1,27 @@
+XEN_ROOT=$(CURDIR)/../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+# In order to link against a package in Go, the package must live in a
+# directory tree in the way that Go expects.  To make this possible,
+# there must be a directory such that we can set GOPATH=${dir}, and
+# the package will be under $GOPATH/src/${full-package-path}.
+
+# So we set XEN_GOPATH to $XEN_ROOT/tools/golang.  The xenlight
+# "package build" directory ($PWD/xenlight) will create the "package
+# source" directory in the proper place.  Go programs can use this
+# package by setting GOPATH=$(XEN_GOPATH).
+
+SUBDIRS-y = xenlight
+
+.PHONY: build all
+all build: subdirs-all
+
+.PHONY: install
+install: subdirs-install
+
+.PHONY: clean
+clean: subdirs-clean
+   $(RM) -r src pkg
+
+.PHONY: distclean
+distclean: clean
diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
new file mode 100644
index 000..5d578f3
--- /dev/null
+++ b/tools/golang/xenlight/Makefile
@@ -0,0 +1,49 @@
+XEN_ROOT=$(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+# Standing boldly against convention, we insist on installing the
+# package source under $(prefix)/share/gocode
+GOCODE_DIR ?= $(prefix)/share/gocode/
+GOXL_PKG_DIR = /src/xenproject.org/xenlight/
+GOXL_INSTALL_DIR = $(GOCODE_DIR)$(GOXL_PKG_DIR)
+
+# PKGSOURCES: Files which comprise the distributed source package
+PKGSOURCES = xenlight.go
+
+GO ?= go
+
+.PHONY: all
+all: build
+
+.PHONY: package
+package: $(XEN_GOPATH)$(GOXL_PKG_DIR)$(PKGSOURCES)
+
+$(XEN_GOPATH)/src/xenproject.org/xenlight/$(PKGSOURCES): $(PKGSOURCES)
+   $(INSTALL_DIR) $(XEN_GOPATH)$(GOXL_PKG_DIR)
+   $(INSTALL_DATA) $(PKGSOURCES) $(XEN_GOPATH)$(GOXL_PKG_DIR)
+
+# Go will do its own dependency checking, and not actuall go through
+# with the build if none of the input files have changed.
+#
+# NB that because the users of this library need to be able to
+# recompile the library from source, it needs to include '-lxenlight'
+# in the LDFLAGS; and thus we need to add -L$(XEN_XENLIGHT) here
+# so that it can find the actual library.
+.PHONY: build
+build: package
+   

Re: [Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-26 Thread Ronald Rojas
On Wed, Jan 25, 2017 at 05:16:47PM +, George Dunlap wrote:
> On Mon, Jan 23, 2017 at 4:43 PM, Ronald Rojas <ronlad...@gmail.com> wrote:
> 
> > +func (Ctx *Context) Open() (err error) {
> > +   if Ctx.ctx != nil {
> > +   return
> > +   }
> > +
> > +   ret := C.libxl_ctx_alloc(unsafe.Pointer(), C.LIBXL_VERSION, 
> > 0, nil)
> 
> Just discovered there's a bug here (in code that I wrote obviously) --
> you can't pass the last argument as nil; you have to include a logger.
> Otherwise if you ever get an error you'll get a NULL dereference. :-)
> 
> I think the fastest thing to do to begin with would be to create a
> "null" logger that just throws away all the data.  Then at some point
> (possibly not in your internship) someone can think about what a
> proper logging interface looks like.

Makes sense. I can modify the code so that it creates an instance of 
the xenlogger and prints it to /dev/null. I will add this in the next
version of the patch.
> 
>  -George

Thanks,
Ronald

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


Re: [Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-26 Thread Ronald Rojas
On Wed, Jan 25, 2017 at 04:55:38PM +, Wei Liu wrote:
> On Mon, Jan 23, 2017 at 11:43:30AM -0500, Ronald Rojas wrote:
> [...]
> > +
> > +subdir-distclean-firmware: .phony
> > +   $(MAKE) -C firmware distclean
> > +
> 
> This looks unrelated.

You're correct. Thanks for catching the mistake.
> 
> >  subdir-clean-debugger/gdbsx subdir-distclean-debugger/gdbsx: .phony
> > $(MAKE) -C debugger/gdbsx clean
> >  
> > diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
> > new file mode 100644
> > index 000..1c2a2b7
> > --- /dev/null
> > +++ b/tools/golang/xenlight/Makefile
> > @@ -0,0 +1,31 @@
> > +XEN_ROOT=$(CURDIR)/../../..
> > +GOLANG_SRC=$(GOPATH)/src/xenproject.org/xenlight
> > +CGO_CFLAGS = -I$(DESTDIR)$(includedir)
> > +CGO_LDFLAGS = -L$(DESTDIR)$(libdir) -Wl,-rpath-link=$(DESTDIR)$(libdir)
> > +include $(XEN_ROOT)/tools/Rules.mk
> > +
> > +BINARY = xenlight.a
> > +GO ?= go
> > +
> > +.PHONY: all
> > +all: build
> > +
> > +.PHONY: build
> > +build: xenlight.a
> > +
> > +.PHONY: install
> > +install: build
> > +   $(INSTALL_DIR) $(DESTDIR)$(GOLANG_SRC)
> > +   $(INSTALL_DATA) xenlight.go $(DESTDIR)$(GOLANG_SRC)
> > +
> > +.PHONY: clean
> > +clean:
> > +   $(RM) $(BINARY)
> > +
> > +.PHONY: distclean
> > +distclean: clean
> > +
> > +xenlight.a: xenlight.go
> > +   CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -o 
> > $@ $<
> > +
> > +-include $(DEPS)
> > diff --git a/tools/golang/xenlight/xenlight.go 
> > b/tools/golang/xenlight/xenlight.go
> > new file mode 100644
> > index 000..f82e14e
> > --- /dev/null
> > +++ b/tools/golang/xenlight/xenlight.go
> > @@ -0,0 +1,86 @@
> > +/*
> > + * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; version 2 of the
> > + * License only.
> > + *
> > + * This program is distributed in the hope that it will be useful, but
> > + * WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> > + * 02110-1301, USA.
> > + */
> 
> My impression is that we prefer LGPL for libraries -- but of course it
> is up to the author to decide what license to use. :-)

Why the preferance for LGPL? I'm not too familiar with the differences
between the two. 
> 
> Wei.

Thanks, 
Ronald

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


[Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-23 Thread Ronald Rojas
Create a basic Makefile to build and install libxenlight Golang
bindings. Also add a stub package which only opens libxl context.

Include a global xenlight.Ctx variable which can be used as the
default context by the entire program if desired.

For now, return simple errors. Proper error handling will be
added in next patch.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/Makefile| 17 
 tools/golang/xenlight/Makefile| 31 ++
 tools/golang/xenlight/xenlight.go | 86 +++
 3 files changed, 134 insertions(+)
 create mode 100644 tools/golang/xenlight/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 77e0723..c1e975f 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -11,6 +11,8 @@ SUBDIRS-y += xenstore
 SUBDIRS-y += misc
 SUBDIRS-y += examples
 SUBDIRS-y += hotplug
+#Uncomment line to build Golang libxl
+#SUBDIRS-y += golang/xenlight
 SUBDIRS-y += xentrace
 SUBDIRS-$(CONFIG_XCUTILS) += xcutils
 SUBDIRS-$(CONFIG_X86) += firmware
@@ -303,6 +305,21 @@ subdir-clean-qemu-xen-dir:
$(MAKE) -C qemu-xen-dir clean; \
fi
 
+subdir-clean-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight clean
+
+subdir-distclean-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight distclean
+
+subdir-install-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight install
+
+subdir-all-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight all
+
+subdir-distclean-firmware: .phony
+   $(MAKE) -C firmware distclean
+
 subdir-clean-debugger/gdbsx subdir-distclean-debugger/gdbsx: .phony
$(MAKE) -C debugger/gdbsx clean
 
diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
new file mode 100644
index 000..1c2a2b7
--- /dev/null
+++ b/tools/golang/xenlight/Makefile
@@ -0,0 +1,31 @@
+XEN_ROOT=$(CURDIR)/../../..
+GOLANG_SRC=$(GOPATH)/src/xenproject.org/xenlight
+CGO_CFLAGS = -I$(DESTDIR)$(includedir)
+CGO_LDFLAGS = -L$(DESTDIR)$(libdir) -Wl,-rpath-link=$(DESTDIR)$(libdir)
+include $(XEN_ROOT)/tools/Rules.mk
+
+BINARY = xenlight.a
+GO ?= go
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: xenlight.a
+
+.PHONY: install
+install: build
+   $(INSTALL_DIR) $(DESTDIR)$(GOLANG_SRC)
+   $(INSTALL_DATA) xenlight.go $(DESTDIR)$(GOLANG_SRC)
+
+.PHONY: clean
+clean:
+   $(RM) $(BINARY)
+
+.PHONY: distclean
+distclean: clean
+
+xenlight.a: xenlight.go
+   CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -o 
$@ $<
+
+-include $(DEPS)
diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
new file mode 100644
index 000..f82e14e
--- /dev/null
+++ b/tools/golang/xenlight/xenlight.go
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+package xenlight
+
+/*
+#cgo LDFLAGS: -lxenlight -lyajl
+#include 
+#include 
+*/
+import "C"
+
+/*
+ * Other flags that may be needed at some point:
+ *  -lnl-route-3 -lnl-3
+ *
+ * To get back to static linking:
+ * #cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
-lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall -lz 
-luuid -lutil
+*/
+
+import (
+   "fmt"
+   "unsafe"
+)
+
+
+/*
+ * Types: Builtins
+ */
+type Context struct {
+   ctx *C.libxl_ctx
+}
+
+/*
+ * 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(), C.LIBXL_VERSION, 0, 
nil)
+
+   if ret != 0 {
+   err = Error(-ret)
+   }
+   return
+}
+
+func (Ctx *Context) Close() (err error) {
+   ret := C.libxl_ctx_free(unsafe.Pointer(Ctx.ctx))
+   Ctx.ctx = nil
+
+   if ret != 0 {
+   err = Error(-ret)
+   }
+   return
+}
+
+func (Ctx *Context) CheckOpen() (err error) {
+   if Ctx.ctx == nil {
+   err = fmt.Errorf("Context not opened")
+   }
+   return
+}
\ No newline at end of file
-- 
2.7.4


___
Xen

[Xen-devel] [PATCH RFC 6/8] golang/xenlight: Implement libxl_bitmap and helper operations

2017-01-23 Thread Ronald Rojas
Implement Bitmap type, along with helper functions.

The Bitmap type is implemented interllay in a way which makes it
easy to copy into and out of the C libxl_bitmap type.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/golang/xenlight/xenlight.go | 166 ++
 1 file changed, 166 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index dd6893c..54692fd 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -131,6 +131,19 @@ func (chwcap C.libxl_hwcap)CToGo() (ghwcap Hwcap) {
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
@@ -199,6 +212,159 @@ type Dominfo struct {
 }
 
 /*
+ * Bitmap operations
+ */
+
+// Return a Go bitmap which is a copy of the referred C bitmap.
+func (cbm C.libxl_bitmap) CToGo() (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 (gbm Bitmap)GoToC() (cbm C.libxl_bitmap) {
+   C.libxl_bitmap_init()
+
+   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-x-x -> 2,4-8,10
+   /// --x-xxx -> 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
+   

[Xen-devel] [PATCH RFC 4/8] golang/xenlight: Implement libxl_domain_info and libxl_domain_unpause

2017-01-23 Thread Ronald Rojas
Add calls for the following host-related functionality:
- libxl_domain_info
- libxl_domain_unpause

Include Golang version for the libxl_domain_info as
DomainInfo.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/golang/xenlight/xenlight.go | 92 +++
 1 file changed, 92 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 92410a8..dd6893c 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -36,6 +36,7 @@ import "C"
 import (
"fmt"
"unsafe"
+   "time"
 )
 
 /*
@@ -104,6 +105,12 @@ var errors = [...]string{
  * Types: Builtins
  */
 
+type Domid uint32
+
+type MemKB uint64
+
+type Uuid C.libxl_uuid
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -165,6 +172,32 @@ type VersionInfo struct {
BuildId  string
 }
 
+type Dominfo struct {
+   Uuid   Uuid
+   Domid  Domid
+   Ssidref uint32
+   SsidLabel string
+   Runningbool
+   Blockedbool
+   Paused bool
+   Shutdown   bool
+   Dying  bool
+   NeverStop bool
+
+   ShutdownReason   int32 // FIXME shutdown_reason enumeration
+   OutstandingMemkb MemKB
+   CurrentMemkb MemKB
+   SharedMemkb  MemKB
+   PagedMemkb   MemKB
+   MaxMemkb MemKB
+   CpuTime  time.Duration
+   VcpuMaxId   uint32
+   VcpuOnline   uint32
+   Cpupool   uint32
+   DomainType   int32 //FIXME libxl_domain_type enumeration
+
+}
+
 /*
  * Context
  */
@@ -343,3 +376,62 @@ func (Ctx *Context) GetVersionInfo() (info *VersionInfo, 
err error) {
 
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(), 
C.uint32_t(Id))
+
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   // We could consider having this boilerplate generated by the
+   // idl, in a function like this:
+   //
+   // di = translateCdomaininfoToGoDomaininfo(cdi)
+   di = {}
+   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 = Error(-ret)
+   }
+   return
+}
-- 
2.7.4


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


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

2017-01-23 Thread Ronald Rojas
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

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/golang/xenlight/xenlight.go | 238 ++
 1 file changed, 238 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 0990f07..c856284 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -273,6 +273,244 @@ func SchedulerFromString(name string) (s Scheduler, err 
error) {
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
+   PoolNamestring
+   Scheduler   Scheduler
+   DomainCount int
+   Cpumap  Bitmap
+}
+
+func (cci C.libxl_cpupoolinfo)CToGo ()(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 = cci.cpumap.CToGo()
+
+   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, )
+
+   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 := cpupoolListSlice[i].CToGo()
+
+   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, _cpupool, C.uint32_t(Poolid))
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+   defer C.libxl_cpupoolinfo_dispose(_cpupool)
+
+   pool = c_cpupool.CToGo()
+
+   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()
+
+   cbm := Cpumap.GoToC()
+   defer C.libxl_bitmap_dispose()
+
+   ret := C.libxl_cpupool_create(Ctx.ctx, name, 
C.libxl_scheduler(Scheduler),
+   cbm, , )
+   if ret != 0 {
+   err = Error(-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 = Error(-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 = Error(-ret)
+   return
+   }
+
+   return
+}
+
+// int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
+// const libxl_bitmap *cpumap);
+func (Ct

[Xen-devel] [PATCH RFC 7/8] golang/xenlight: Implement libxl_scheduler enumeration

2017-01-23 Thread Ronald Rojas
Include both constants and a Stringification for libxl_scheduler.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/golang/xenlight/xenlight.go | 62 +++
 1 file changed, 62 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 54692fd..0990f07 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -211,6 +211,68 @@ type Dominfo struct {
 
 }
 
+// # 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, )
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   *s = Scheduler(cs)
+   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, )
+   if ret != 0 {
+   err = Error(-ret)
+   return
+   }
+
+   s = Scheduler(cs)
+
+   return
+}
+
 /*
  * Bitmap operations
  */
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 2/8] golang/xenlight: Add error constants and standard handling

2017-01-23 Thread Ronald Rojas
Create error type Errorxl for throwing proper xenlight
errors.

Update Ctx functions to throw Errorxl errors.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/golang/xenlight/xenlight.go | 75 ++-
 1 file changed, 74 insertions(+), 1 deletion(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index f82e14e..eee2254 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -38,10 +38,72 @@ import (
"unsafe"
 )
 
+/*
+ * Errors
+ */
+
+type Error int
+
+const (
+   ErrorNonspecific  = Error(-C.ERROR_NONSPECIFIC)
+   ErrorVersion  = Error(-C.ERROR_VERSION)
+   ErrorFail = Error(-C.ERROR_FAIL)
+   ErrorNi   = Error(-C.ERROR_NI)
+   ErrorNomem= Error(-C.ERROR_NOMEM)
+   ErrorInval= Error(-C.ERROR_INVAL)
+   ErrorBadfail  = Error(-C.ERROR_BADFAIL)
+   ErrorGuestTimedout= Error(-C.ERROR_GUEST_TIMEDOUT)
+   ErrorTimedout = Error(-C.ERROR_TIMEDOUT)
+   ErrorNoparavirt   = Error(-C.ERROR_NOPARAVIRT)
+   ErrorNotReady = Error(-C.ERROR_NOT_READY)
+   ErrorOseventRegFail   = Error(-C.ERROR_OSEVENT_REG_FAIL)
+   ErrorBufferfull   = Error(-C.ERROR_BUFFERFULL)
+   ErrorUnknownChild = Error(-C.ERROR_UNKNOWN_CHILD)
+   ErrorLockFail = Error(-C.ERROR_LOCK_FAIL)
+   ErrorJsonConfigEmpty  = Error(-C.ERROR_JSON_CONFIG_EMPTY)
+   ErrorDeviceExists = Error(-C.ERROR_DEVICE_EXISTS)
+   ErrorCheckpointDevopsDoesNotMatch = 
Error(-C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
+   ErrorCheckpointDeviceNotSupported = 
Error(-C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
+   ErrorVnumaConfigInvalid   = Error(-C.ERROR_VNUMA_CONFIG_INVALID)
+   ErrorDomainNotfound   = Error(-C.ERROR_DOMAIN_NOTFOUND)
+   ErrorAborted  = Error(-C.ERROR_ABORTED)
+   ErrorNotfound = Error(-C.ERROR_NOTFOUND)
+   ErrorDomainDestroyed  = Error(-C.ERROR_DOMAIN_DESTROYED)
+   ErrorFeatureRemoved   = Error(-C.ERROR_FEATURE_REMOVED)
+)
+
+var errors = [...]string{
+   ErrorNonspecific: "Non-specific error",
+   ErrorVersion: "Wrong version",
+   ErrorFail: "Failed",
+   ErrorNi: "Not Implemented",
+   ErrorNomem: "No memory",
+   ErrorInval: "Invalid argument",
+   ErrorBadfail: "Bad Fail",
+   ErrorGuestTimedout: "Guest timed out",
+   ErrorTimedout: "Timed out",
+   ErrorNoparavirt: "No Paravirtualization",
+   ErrorNotReady: "Not ready",
+   ErrorOseventRegFail: "OS event registration failed",
+   ErrorBufferfull: "Buffer full",
+   ErrorUnknownChild: "Unknown child",
+   ErrorLockFail: "Lock failed",
+   ErrorJsonConfigEmpty: "JSON config empty",
+   ErrorDeviceExists: "Device exists",
+   ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does not match",
+   ErrorCheckpointDeviceNotSupported: "Checkpoint device not supported",
+   ErrorVnumaConfigInvalid: "VNUMA config invalid",
+   ErrorDomainNotfound: "Domain not found",
+   ErrorAborted: "Aborted",
+   ErrorNotfound: "Not found",
+   ErrorDomainDestroyed: "Domain destroyed",
+   ErrorFeatureRemoved: "Feature removed",
+}
 
 /*
  * Types: Builtins
  */
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -51,6 +113,17 @@ type Context struct {
  */
 var Ctx Context
 
+func (e Error) Error() string{
+   if 0< int(e) && int(e) < len(errors){
+   s:= errors[e]
+   if s != ""{
+   return s
+   }
+   }
+   return fmt.Sprintf("libxl error: %d", -e)
+
+}
+
 func (Ctx *Context) IsOpen() bool {
return Ctx.ctx != nil
 }
@@ -83,4 +156,4 @@ func (Ctx *Context) CheckOpen() (err error) {
err = fmt.Errorf("Context not opened")
}
return
-}
\ No newline at end of file
+}
-- 
2.7.4


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


Re: [Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-19 Thread Ronald Rojas
On Thu, Jan 19, 2017 at 12:03:22PM +, Wei Liu wrote:
> On Wed, Jan 18, 2017 at 02:56:39PM -0500, Ronald Rojas wrote:
>   
> > diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
> > new file mode 100644
> > index 000..a45336b
> > --- /dev/null
> > +++ b/tools/golang/xenlight/Makefile
> > @@ -0,0 +1,29 @@
> > +XEN_ROOT=$(CURDIR)/../../..
> > +include $(XEN_ROOT)/tools/Rules.mk
> > +
> > +BINARY = xenlightgo
> > +GO = go
> 
> GO ?= go
> 
> to allow overriding this command.

Fixed. Thanks!
> 
> Other than this, I don't have further comments on the actual go code and
> will let George review your series.
> 
> Wei.

Thanks,
Ronald

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


Re: [Xen-devel] [PATCH RFC 2/8] golang/xenlight: Add error constants and standard handling

2017-01-19 Thread Ronald Rojas
On Wed, Jan 18, 2017 at 11:16:31PM +0100, Dario Faggioli wrote:
> On Wed, 2017-01-18 at 14:56 -0500, Ronald Rojas wrote:
> > Create error type Errorxl for throwing proper xenlight
> > errors.
> > 
> > Update Ctx functions to throw Errorxl errors.
> > 
> > Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
> > ---
> >  tools/golang/xenlight/xenlight.go | 77
> > +--
> >  1 file changed, 73 insertions(+), 4 deletions(-)
> > 
> > diff --git a/tools/golang/xenlight/xenlight.go
> > b/tools/golang/xenlight/xenlight.go
> > index 1f10e51..d58f8b8 100644
> > --- a/tools/golang/xenlight/xenlight.go
> > +++ b/tools/golang/xenlight/xenlight.go
> > @@ -32,6 +32,77 @@ import (
> >  )
> >  
> >  /*
> > + * Errors
> > + */
> > +type Errorxl int
> > +
> > +const (
> > +   ErrorNonspecific  = Errorxl(-
> > C.ERROR_NONSPECIFIC)
> > +   ErrorVersion  = Errorxl(-
> > C.ERROR_VERSION)
> > +   ErrorFail = Errorxl(-C.ERROR_FAIL)
> > +   ErrorNi   = Errorxl(-C.ERROR_NI)
> > +   ErrorNomem= Errorxl(-C.ERROR_NOMEM)
> > +   ErrorInval= Errorxl(-C.ERROR_INVAL)
> > +   ErrorBadfail  = Errorxl(-
> > C.ERROR_BADFAIL)
> > +   ErrorGuestTimedout= Errorxl(-
> > C.ERROR_GUEST_TIMEDOUT)
> > +   ErrorTimedout = Errorxl(-
> > C.ERROR_TIMEDOUT)
> > +   ErrorNoparavirt   = Errorxl(-
> > C.ERROR_NOPARAVIRT)
> > +   ErrorNotReady = Errorxl(-
> > C.ERROR_NOT_READY)
> > +   ErrorOseventRegFail   = Errorxl(-
> > C.ERROR_OSEVENT_REG_FAIL)
> > +   ErrorBufferfull   = Errorxl(-
> > C.ERROR_BUFFERFULL)
> > +   ErrorUnknownChild = Errorxl(-
> > C.ERROR_UNKNOWN_CHILD)
> > +   ErrorLockFail = Errorxl(-
> > C.ERROR_LOCK_FAIL)
> > +   ErrorJsonConfigEmpty  = Errorxl(-
> > C.ERROR_JSON_CONFIG_EMPTY)
> > +   ErrorDeviceExists = Errorxl(-
> > C.ERROR_DEVICE_EXISTS)
> > +   ErrorCheckpointDevopsDoesNotMatch = Errorxl(-
> > C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
> > +   ErrorCheckpointDeviceNotSupported = Errorxl(-
> > C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
> > +   ErrorVnumaConfigInvalid   = Errorxl(-
> > C.ERROR_VNUMA_CONFIG_INVALID)
> > +   ErrorDomainNotfound   = Errorxl(-
> > C.ERROR_DOMAIN_NOTFOUND)
> > +   ErrorAborted  = Errorxl(-
> > C.ERROR_ABORTED)
> > +   ErrorNotfound = Errorxl(-
> > C.ERROR_NOTFOUND)
> > +   ErrorDomainDestroyed  = Errorxl(-
> > C.ERROR_DOMAIN_DESTROYED)
> > +   ErrorFeatureRemoved   = Errorxl(-
> > C.ERROR_FEATURE_REMOVED)
> > +)
> > +
> > +var errors = [...]string{
> > +   ErrorNonspecific:  "Non-specific error",
> > +   ErrorVersion:  "Wrong version",
> > +   ErrorFail: "Failed",
> > +   ErrorNi:   "Null",
> > +   ErrorNomem:"No memory",
> > +   ErrorInval:"Invalid",
> > +   ErrorBadfail:  "Bad Fail",
> > +   ErrorGuestTimedout:"Guest timed out",
> > +   ErrorTimedout: "Timed out",
> > +   ErrorNoparavirt:   "No Paravirtualization",
> > +   ErrorNotReady: "Not ready",
> > +   ErrorOseventRegFail:   "OS event failed",
> > +   ErrorBufferfull:   "Buffer full",
> > +   ErrorUnknownChild: "Unknown child",
> > +   ErrorLockFail: "Lock failed",
> > +   ErrorJsonConfigEmpty:  "JSON config empyt",
> > +   ErrorDeviceExists: "Device exists",
> > +   ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does
> > not match",
> > +   ErrorCheckpointDeviceNotSupported: "Checkpoint device not
> > supported",
> > +   ErrorVnumaConfigInvalid:   "VNUMA config invalid",
> > +   ErrorDomainNotfound:   "Domain not found",
> > +   ErrorAborted:  "Aborted&quo

Re: [Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-18 Thread Ronald Rojas
On Wed, Jan 18, 2017 at 11:10:32PM +0100, Dario Faggioli wrote:
> Hey,
> 
> I'm afraid I can't comment on nothing, as I'm not at all into go.
> 
> But there's a thing that I've noticed while skipping the patch out of
> curiosity...
> 
> On Wed, 2017-01-18 at 14:56 -0500, Ronald Rojas wrote:
> > diff --git a/tools/Makefile b/tools/Makefile
> > index 77e0723..fd49e7f 100644
> > --- a/tools/Makefile
> > +++ b/tools/Makefile
> > @@ -6,12 +6,13 @@ SUBDIRS-y += include
> >  SUBDIRS-y += libs
> >  SUBDIRS-y += libxc
> >  SUBDIRS-y += flask
> > -SUBDIRS-y += fuzz
> >
> Why does this needs to be removed?
This was a mistake and should not have been removed. I'll
fix it in the next revision.

Thanks, 
Ronald
> 
> Dario
> -- 
> <> (Raistlin Majere)
> -
> Dario Faggioli, Ph.D, http://about.me/dario.faggioli
> Senior Software Engineer, Citrix Systems R Ltd., Cambridge (UK)



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


[Xen-devel] [PATCH RFC 6/8] tools/xenlight: Implement libxl_scheduler enumeration

2017-01-18 Thread Ronald Rojas
Include both constants and a Stringification for libxl_scheduler.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/golang/xenlight/xenlight.go | 72 +++
 1 file changed, 72 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 8aaca6a..64e867a 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -211,6 +211,78 @@ type Dominfo struct {
 
 }
 
+// # 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, )
+   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, )
+   if ret != 0 {
+   err = Errorxl(ret)
+   return
+   }
+
+   s = Scheduler(cs)
+
+   return
+}
+
 /*
  * Bitmap operations
  */
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 2/8] golang/xenlight: Add error constants and standard handling

2017-01-18 Thread Ronald Rojas
Create error type Errorxl for throwing proper xenlight
errors.

Update Ctx functions to throw Errorxl errors.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/golang/xenlight/xenlight.go | 77 +--
 1 file changed, 73 insertions(+), 4 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 1f10e51..d58f8b8 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -32,6 +32,77 @@ import (
 )
 
 /*
+ * Errors
+ */
+type Errorxl int
+
+const (
+   ErrorNonspecific  = Errorxl(-C.ERROR_NONSPECIFIC)
+   ErrorVersion  = Errorxl(-C.ERROR_VERSION)
+   ErrorFail = Errorxl(-C.ERROR_FAIL)
+   ErrorNi   = Errorxl(-C.ERROR_NI)
+   ErrorNomem= Errorxl(-C.ERROR_NOMEM)
+   ErrorInval= Errorxl(-C.ERROR_INVAL)
+   ErrorBadfail  = Errorxl(-C.ERROR_BADFAIL)
+   ErrorGuestTimedout= Errorxl(-C.ERROR_GUEST_TIMEDOUT)
+   ErrorTimedout = Errorxl(-C.ERROR_TIMEDOUT)
+   ErrorNoparavirt   = Errorxl(-C.ERROR_NOPARAVIRT)
+   ErrorNotReady = Errorxl(-C.ERROR_NOT_READY)
+   ErrorOseventRegFail   = Errorxl(-C.ERROR_OSEVENT_REG_FAIL)
+   ErrorBufferfull   = Errorxl(-C.ERROR_BUFFERFULL)
+   ErrorUnknownChild = Errorxl(-C.ERROR_UNKNOWN_CHILD)
+   ErrorLockFail = Errorxl(-C.ERROR_LOCK_FAIL)
+   ErrorJsonConfigEmpty  = Errorxl(-C.ERROR_JSON_CONFIG_EMPTY)
+   ErrorDeviceExists = Errorxl(-C.ERROR_DEVICE_EXISTS)
+   ErrorCheckpointDevopsDoesNotMatch = 
Errorxl(-C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
+   ErrorCheckpointDeviceNotSupported = 
Errorxl(-C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
+   ErrorVnumaConfigInvalid   = 
Errorxl(-C.ERROR_VNUMA_CONFIG_INVALID)
+   ErrorDomainNotfound   = Errorxl(-C.ERROR_DOMAIN_NOTFOUND)
+   ErrorAborted  = Errorxl(-C.ERROR_ABORTED)
+   ErrorNotfound = Errorxl(-C.ERROR_NOTFOUND)
+   ErrorDomainDestroyed  = Errorxl(-C.ERROR_DOMAIN_DESTROYED)
+   ErrorFeatureRemoved   = Errorxl(-C.ERROR_FEATURE_REMOVED)
+)
+
+var errors = [...]string{
+   ErrorNonspecific:  "Non-specific error",
+   ErrorVersion:  "Wrong version",
+   ErrorFail: "Failed",
+   ErrorNi:   "Null",
+   ErrorNomem:"No memory",
+   ErrorInval:"Invalid",
+   ErrorBadfail:  "Bad Fail",
+   ErrorGuestTimedout:"Guest timed out",
+   ErrorTimedout: "Timed out",
+   ErrorNoparavirt:   "No Paravirtualization",
+   ErrorNotReady: "Not ready",
+   ErrorOseventRegFail:   "OS event failed",
+   ErrorBufferfull:   "Buffer full",
+   ErrorUnknownChild: "Unknown child",
+   ErrorLockFail: "Lock failed",
+   ErrorJsonConfigEmpty:  "JSON config empyt",
+   ErrorDeviceExists: "Device exists",
+   ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does not match",
+   ErrorCheckpointDeviceNotSupported: "Checkpoint device not supported",
+   ErrorVnumaConfigInvalid:   "VNUMA config invalid",
+   ErrorDomainNotfound:   "Domain not found",
+   ErrorAborted:  "Aborted",
+   ErrorNotfound: "Not found",
+   ErrorDomainDestroyed:  "Domain destroyed",
+   ErrorFeatureRemoved:   "Feature removed",
+}
+
+func (e Errorxl) Error() string {
+   if 0 <= -int(e) && -int(e) < len(errors) {
+   s := errors[-e]
+   if s != "" {
+   return s
+   }
+   }
+   return "errorxl " + strconv.Itoa(int(e))
+}
+
+/*
  * Types: Builtins
  */
 type Context struct {
@@ -55,8 +126,7 @@ func (Ctx *Context) Open() (err error) {
ret := C.libxl_ctx_alloc(unsafe.Pointer(), C.LIBXL_VERSION, 0, 
nil)
 
if ret != 0 {
-   //FIXME: proper error
-   err = createError("Allocating libxl context: ", ret)
+   err = Errorxl(ret)
}
return
 }
@@ -66,8 +136,7 @@ func (Ctx *Context

[Xen-devel] [PATCH RFC 1/8] golang/xenlight: Create stub package

2017-01-18 Thread Ronald Rojas
Create a basic Makefile to build and install libxenlight Golang
bindings. Also add a stub package which only opens libxl context.

Include a global xenlight.Ctx variable which can be used as the
default context by the entire program if desired.

For now, return simple errors. Proper error handling will be
added in next patch.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/Makefile| 15 +++-
 tools/golang/xenlight/Makefile| 29 ++
 tools/golang/xenlight/xenlight.go | 80 +++
 3 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 tools/golang/xenlight/Makefile
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/Makefile b/tools/Makefile
index 77e0723..fd49e7f 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -6,12 +6,13 @@ SUBDIRS-y += include
 SUBDIRS-y += libs
 SUBDIRS-y += libxc
 SUBDIRS-y += flask
-SUBDIRS-y += fuzz
 SUBDIRS-y += xenstore
 SUBDIRS-y += misc
 SUBDIRS-y += examples
 SUBDIRS-y += hotplug
 SUBDIRS-y += xentrace
+#Uncomment line to build Golang libxl
+#SUBDIRS-y += golang/xenlight
 SUBDIRS-$(CONFIG_XCUTILS) += xcutils
 SUBDIRS-$(CONFIG_X86) += firmware
 SUBDIRS-y += console
@@ -322,6 +323,18 @@ subdir-install-debugger/kdd: .phony
 subdir-all-debugger/kdd: .phony
$(MAKE) -C debugger/kdd all
 
+subdir-clean-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight clean
+
+subdir-distclean-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight distclean
+
+subdir-install-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight install
+
+subdir-all-golang/xenlight: .phony
+   $(MAKE) -C golang/xenlight all
+
 subdir-distclean-firmware: .phony
$(MAKE) -C firmware distclean
 
diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
new file mode 100644
index 000..a45336b
--- /dev/null
+++ b/tools/golang/xenlight/Makefile
@@ -0,0 +1,29 @@
+XEN_ROOT=$(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+BINARY = xenlightgo
+GO = go
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: xenlight
+
+.PHONY: install
+install: build
+   ! [ -f $(BINARY) ] || $(INSTALL_PROG) xenlight.go $(DESTDIR)$(bindir)
+
+.PHONY: clean
+clean:
+   $(RM) $(BINARY)
+
+.PHONY: distclean
+distclean: clean
+
+
+xenlight: xenlight.go
+   $(GO) build -o $(BINARY) xenlight.go
+
+
+-include $(DEPS)
diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
new file mode 100644
index 000..1f10e51
--- /dev/null
+++ b/tools/golang/xenlight/xenlight.go
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+package xenlight
+
+/*
+#cgo LDFLAGS: -lxenlight -lyajl
+#include 
+#include 
+*/
+import "C"
+
+import (
+   "fmt"
+   "time"
+   "unsafe"
+)
+
+/*
+ * Types: Builtins
+ */
+type Context struct {
+   ctx *C.libxl_ctx
+}
+
+/*
+ * 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(), C.LIBXL_VERSION, 0, 
nil)
+
+   if ret != 0 {
+   //FIXME: proper error
+   err = createError("Allocating libxl context: ", ret)
+   }
+   return
+}
+
+func (Ctx *Context) Close() (err error) {
+   ret := C.libxl_ctx_free(unsafe.Pointer(Ctx.ctx))
+   Ctx.ctx = nil
+
+   if ret != 0 {
+   //FIXME: proper error
+   err = createError("Freeing libxl context: ", ret)
+   }
+   return
+}
+
+func (Ctx *Context) CheckOpen() (err error) {
+   if Ctx.ctx == nil {
+   err = fmt.Errorf("Context not opened")
+   }
+   return
+}
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 5/8] golang/xenlight: Implement libxl_bitmap and helper operations

2017-01-18 Thread Ronald Rojas
Implement Bitmap type, along with helper functions.

The Bitmap type is implemented interllay in a way which makes it
easy to copy into and out of the C libxl_bitmap type.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/golang/xenlight/xenlight.go | 167 ++
 1 file changed, 167 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 1e25413..8aaca6a 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -131,6 +131,20 @@ func hwcapCToGo(chwcap C.libxl_hwcap) (ghwcap Hwcap) {
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
  *
@@ -198,6 +212,159 @@ type Dominfo struct {
 }
 
 /*
+ * 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()
+
+   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-x-x -> 2,4-8,10
+   /// --x-xxx -> 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
+   

[Xen-devel] [PATCH RFC 4/8] golang/xenlight: Implement libxl_domain_info and libxl_domain_unpause

2017-01-18 Thread Ronald Rojas
Add calls for the following host-related functionality:
- libxl_domain_info
- libxl_domain_unpause

Include Golang version for the libxl_domain_info as
DomainInfo.

Signed-off-by: George Dunlap <george.dun...@citrix.com>
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/golang/xenlight/xenlight.go | 91 +++
 1 file changed, 91 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index 6b04850..1e25413 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -105,6 +105,12 @@ func (e Errorxl) Error() string {
 /*
  * Types: Builtins
  */
+type Domid uint32
+
+type MemKB uint64
+
+type Uuid C.libxl_uuid
+
 type Context struct {
ctx *C.libxl_ctx
 }
@@ -165,6 +171,32 @@ type VersionInfo struct {
BuildId string
 }
 
+type Dominfo struct {
+   Uuid  Uuid
+   Domid Domid
+   Ssidref   uint32
+   SsidLabel string
+   Running   bool
+   Blocked   bool
+   Pausedbool
+   Shutdown  bool
+   Dying bool
+   NeverStop bool
+
+   ShutdownReason   int32 // FIXME shutdown_reason enumeration
+   OutstandingMemkb MemKB
+   CurrentMemkb MemKB
+   SharedMemkb  MemKB
+   PagedMemkb   MemKB
+   MaxMemkb MemKB
+   CpuTime  time.Duration
+   VcpuMaxIduint32
+   VcpuOnline   uint32
+   Cpupool  uint32
+   DomainType   int32 //FIXME libxl_domain_type enumeration
+
+}
+
 /*
  * Context
  */
@@ -332,3 +364,62 @@ func (Ctx *Context) GetVersionInfo() (info *VersionInfo, 
err error) {
 
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(), 
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 = {}
+   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
+}
-- 
2.7.4


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


[Xen-devel] libxl to json return string

2017-01-12 Thread Ronald Rojas
Hi,
I have an example attached below where I believe that libxl_physinfo_to_json() 
does not return all of the correct output. physinfo.c is the C program that 
outputs the json string. physc.out is the output that I recieved. physgo.out 
is the output I get using the golang bindings I'm creating for xenlight. 
The missing fields are :
scrub_pages, outstanding_pages, sharing_freed_pages,sharing_used_frames, 
the last 4 indices of hw_cap, cap_hvm, and cap_hvm_directio

I had a similar problem with libxl_dominfo_to_json() where some data fields
were not added to the string. 

It was said on the IRC channel that default values are not converted to json,
but is there a way to tell what is the default value for a data field?

Thanks!
Ronald Rojas
{
"threads_per_core": 1,
"cores_per_socket": 4,
"max_cpu_id": 3,
"nr_cpus": 4,
"cpu_khz": 3198157,
"total_pages": 4179453,
"free_pages": 32702,
"nr_nodes": 1,
"hw_cap": [
3085695999,
2012935103,
739248128,
33
]
}

{
"Threads_per_core": 1,
"Cores_per_socket": 4,
"Max_cpu_id": 3,
"Nr_cpus": 4,
"Cpu_khz": 3198157,
"Total_pages": 4179453,
"Free_pages": 32702,
"Scrub_pages": 0,
"Outstanding_pages": 0,
"Sharing_freed_pages": 0,
"Sharing_used_frames": 0,
"Nr_nodes": 1,
"Hw_cap": [
3085695999,
2012935103,
739248128,
33,
1,
10155,
0,
256
],
"Cap_hvm": false,
"Cap_hvm_directio": false
}
#include 
#include 
#include 

char * main(){

libxl_ctx *context;
libxl_ctx_alloc(,LIBXL_VERSION, 0, NULL);
libxl_physinfo info ;
int err= libxl_get_physinfo(context, );
if(err != 0){
 return NULL;
}



char * json= libxl_physinfo_to_json(context, );

libxl_ctx_free(context);
return json;

}
___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RFC 59/59] tools/xenlight: Create interface for xenlight info

2017-01-03 Thread Ronald Rojas
On Thu, Dec 29, 2016 at 01:45:54PM +, George Dunlap wrote:
> Hey Ronald!  Looks like you're getting going pretty well here.
> 
> At a high level: I think I began by saying that this would probably all
> be a single patch.  But I think it would probably be easier to review
> the different decisions made at each point by filling out the file bit
> by bit, and explaining what's going on at each point.
> 
> I think also it would be helpful to have somewhere -- either in a
> comment or in a text file -- a description of the general approach to
> converting the libxl C style into xenlight golang style.  For instance,
> saying that for functions, we'll take the function name
> (libxl_cpupool_remove), remove the libxl_ prefix (since the packages are
> namespaced already) and convert it to CamelCase by capitalizing the first
> 
> I'll take a stab at breaking it down in an example order that makes some
> sense to me, and then you can see what you think.

I made some guidelines that I think would nicely adjust the naming convention
from C to Go. I'll add it as a file below.
> 
> Futher comments...
> 
> On 29/12/16 01:14, Ronald Rojas wrote:
> > diff --git a/tools/golang/xenlight/xenlight.go 
> > b/tools/golang/xenlight/xenlight.go
> > new file mode 100644
> > index 000..b0eb6f8
> > --- /dev/null
> > +++ b/tools/golang/xenlight/xenlight.go
> > @@ -0,0 +1,1000 @@
> > +/*
> > + * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; version 2 of the
> > + * License only.
> > + *
> > + * This program is distributed in the hope that it will be useful, but
> > + * WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> > + * 02110-1301, USA.
> > + */
> > +package xenlight
> > +
> > +/*
> > +#cgo LDFLAGS: -lxenlight -lyajl
> > +#include 
> > +#include 
> > +*/
> > +import "C"
> 
> I see you switched back to dynamic linking -- any particular reason?
> 
> We probably need to put a "// FIXME" here saying that we need to
> generate these compile-time dependencies using pkg-config.

We discussed this on IRC but I'll just restate here that I was not able 
to compile the program through static linking and it would be fine to 
just use dynamic linking for now.
Since we are doing dynamic linking do we still need to use pkg-config?
> 
> > +
> > +/*
> > + * Other flags that may be needed at some point:
> > + *  -lnl-route-3 -lnl-3
> > +#cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
> > -lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall 
> > -lz -luuid -lutil
> > + *
> > + * To get back to simple dynamic linking:
> > +*/
> 
> Comment needs updating (to "To use static linking").

Fixed.
> 
> > +
> > +import (
> > +   "fmt"
> > +   "time"
> > +   "unsafe"
> > +)
> > +
> > +/*
> > + * Errors
> > + */
> > +const (
> > +   ErrorNonspecific  = int(C.ERROR_NONSPECIFIC)
> > +   ErrorVersion  = int(C.ERROR_VERSION)
> > +   ErrorFail = int(C.ERROR_FAIL)
> > +   ErrorNi   = int(C.ERROR_NI)
> > +   ErrorNomem= int(C.ERROR_NOMEM)
> > +   ErrorInval= int(C.ERROR_INVAL)
> > +   ErrorBadfail  = int(C.ERROR_BADFAIL)
> > +   ErrorGuestTimedout= int(C.ERROR_GUEST_TIMEDOUT)
> > +   ErrorTimedout = int(C.ERROR_TIMEDOUT)
> > +   ErrorNoparavirt   = int(C.ERROR_NOPARAVIRT)
> > +   ErrorNotReady = int(C.ERROR_NOT_READY)
> > +   ErrorOseventRegFail   = int(C.ERROR_OSEVENT_REG_FAIL)
> > +   ErrorBufferfull   = int(C.ERROR_BUFFERFULL)
> > +   ErrorUnknownChild = int(C.ERROR_UNKNOWN_CHILD)
> > +   ErrorLockFail = int(C.ERROR_LOCK_FAIL)
> > +   ErrorJsonConfigEmpty  = int(C.ERROR_JSON_CONFIG_EMPTY)
>

Re: [Xen-devel] [PATCH RFC 59/59] tools/xenlight: Create interface for xenlight info

2016-12-29 Thread Ronald Rojas
On Thu, Dec 29, 2016 at 10:52:42AM +, Wei Liu wrote:
> On Thu, Dec 29, 2016 at 10:34:34AM +, George Dunlap wrote:
> > On 29/12/16 01:14, Ronald Rojas wrote:
> > > Create interface to interact with libxl_verions_info
> > > and libxl_physinfo. Also introduce proper error
> > > handling.
> > > 
> > > Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
> > 
> > Hey Ronald,
> > 
> > When you send a series to a public open-source project, you want it to
> > be a sort of idealized set of changes that make it easy to "see the
> > forest for the trees", as it were, not the actual local development
> > path.  We don't need the full development history of libxl.go -- a
> > simple dump will be fine; and we definitely don't need all the other
> > stuff from schedbench in the xen.git history. :-)
> > 
> > All you needed to do to "import" my existing libxl code from schedbench was:
> > 
> > $ cd xen.git
> > $ cp ../schedbench.git/controller/libxl.go tools/golang/xenlight/xenlight.go
> > $ git add tools/golang/xenlight/xenlight.go

This is much easier then what I was doing. I did it another way 
because I thought you would have wanted to keep the git commit 
history. I can resubmit the patch into 2 commits so it'll be 
easier to read. 1 for importing the code from schedbench and 
then the changes that I made afterward. How does that sound?
> > 
> 
> +1 for this.

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


[Xen-devel] [PATCH RFC 54/59] controller/run: Add RunConfig.NumaDisable

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

If RunConfig.NumaDisable is set, get each worker's
WorkerConfig.SoftAffinity to the cpumap of the cpupool the VM is going
to be running in.

Signed-off-by: George Dunlap 
---
 benchmark.go |  4 
 run.go   | 35 ---
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index d5a0ac8..abe2dfb 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -142,6 +142,7 @@ type RunConfig struct {
Scheduler string
Pool string
Cpus []int
+   NumaDisable *bool `json:",omitempty"`
 }
 
 // Propagate unset values from a higher level
@@ -155,6 +156,9 @@ func (l *RunConfig) PropagateFrom(g RunConfig) {
if l.Cpus == nil {
l.Cpus = g.Cpus
}
+   if l.NumaDisable == nil {
+   l.NumaDisable = g.NumaDisable
+   }
 }
 
 type BenchmarkRun struct {
diff --git a/run.go b/run.go
index 2d0db01..d1c5d95 100644
--- a/run.go
+++ b/run.go
@@ -312,14 +312,43 @@ func (run *BenchmarkRun) Prep() (ready bool, why string) {
return 
 }
 
+func (run *BenchmarkRun) GetCpumap() (Cpumap Bitmap) {
+   if run.RunConfig.Pool == "" {
+   fmt.Printf("Run.Prep: No pool set, using 0\n")
+   pool := Ctx.CpupoolInfo(0)
+   Cpumap = pool.Cpumap
+   } else {
+   pool, poolPresent := Ctx.CpupoolFindByName(run.RunConfig.Pool)
+   if poolPresent {
+   Cpumap = pool.Cpumap
+   } else {
+   panic("run.GetCpumap(): Pool "+run.RunConfig.Pool+" not 
found!")
+   }
+   }
+   return
+}
+
 func (run *BenchmarkRun) Run() (err error) {
for wsi := range run.WorkerSets {
-   run.WorkerSets[wsi].Config.PropagateFrom(run.WorkerConfig)
-   if run.WorkerSets[wsi].Config.Pool == "" {
-   run.WorkerSets[wsi].Config.Pool = run.RunConfig.Pool
+   conf := [wsi].Config
+   
+   conf.PropagateFrom(run.WorkerConfig)
+   if conf.Pool == "" {
+   conf.Pool = run.RunConfig.Pool
}
run.WorkerSets[wsi].Params.SetkHZ(CpukHZ)

+   if *run.RunConfig.NumaDisable {
+   if conf.SoftAffinity != "" {
+   err = fmt.Errorf("Cannot disable Numa if 
SoftAffinity is set!")
+   return
+   }
+   // Disable libxl NUMA by setting the soft
+   // affinity to the set of cpus in the cpupool
+   conf.SoftAffinity = run.GetCpumap().String()
+   fmt.Printf("Setting SoftAffinity to %s to disable NUMA 
placement\n",
+   conf.SoftAffinity)
+   }
}

Workers, err := NewWorkerList(run.WorkerSets, WorkerXen)
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 59/59] tools/xenlight: Create interface for xenlight info

2016-12-28 Thread Ronald Rojas
Create interface to interact with libxl_verions_info
and libxl_physinfo. Also introduce proper error
handling.

Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 tools/golang/xenlight/libxl.go|  720 --
 tools/golang/xenlight/xenlight.go | 1000 +
 2 files changed, 1000 insertions(+), 720 deletions(-)
 delete mode 100644 tools/golang/xenlight/libxl.go
 create mode 100644 tools/golang/xenlight/xenlight.go

diff --git a/tools/golang/xenlight/libxl.go b/tools/golang/xenlight/libxl.go
deleted file mode 100644
index aa5c01c..000
--- a/tools/golang/xenlight/libxl.go
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of the
- * License only.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-package main
-
-/*
-#cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
-lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall -lz 
-luuid -lutil
-#include 
-#include 
-*/
-import "C"
-
-/*
- * Other flags that may be needed at some point: 
- *  -lnl-route-3 -lnl-3
- *
- * To get back to simple dynamic linking:
-#cgo LDFLAGS: -lxenlight -lyajl
-*/
-
-import (
-   "unsafe"
-   "fmt"
-   "time"
-)
-
-/*
- * Types: Builtins
- */
-
-type Domid uint32
-
-type MemKB uint64
-
-// 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
-}
-
-type Context struct {
-   ctx *C.libxl_ctx
-}
-
-type Uuid C.libxl_uuid
-
-/*
- * Types: IDL
- * 
- * FIXME: Generate these automatically from the IDL
- */
-type Dominfo struct {
-   Uuid  Uuid
-   Domid Domid
-   Running   bool
-   Blocked   bool
-   Pausedbool
-   Shutdown  bool
-   Dying bool
-   Never_stopbool
-   
-   Shutdown_reason   int32 // FIXME shutdown_reason enumeration
-   Outstanding_memkb MemKB
-   Current_memkb MemKB
-   Shared_memkb  MemKB
-   Paged_memkb   MemKB
-   Max_memkb MemKB
-   Cpu_time  time.Duration
-   Vcpu_max_id   uint32
-   Vcpu_online   uint32
-   Cpupool   uint32
-   Domain_type   int32 //FIXME libxl_domain_type enumeration
-
-}
-
-// # 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
-)
-
-// 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
-}
-
-/*
- * 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(), C.LIBXL_VERSION, 0, 
nil)
-
-   if ret != 0 {
-   err = fmt.Errorf("Allocating libxl contex

[Xen-devel] [PATCH RFC 56/59] controller/plan: Add NumaDisable to SimpleMatrix

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 plan.go | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/plan.go b/plan.go
index 736d9f3..b8e0c6b 100644
--- a/plan.go
+++ b/plan.go
@@ -26,6 +26,7 @@ type PlanSimpleMatrix struct {
Schedulers []string
Workers []string
Count []int
+   NumaDisable []bool
 }
 
 type PlanInput struct {
@@ -127,6 +128,27 @@ func (plan *BenchmarkPlan) ExpandInput() (err error) {
b = nil
}
 
+   // ...and NumaDisable
+   if len(plan.Input.SimpleMatrix.NumaDisable) > 0 {
+   for _, base := range a {
+   for _, d := range plan.Input.SimpleMatrix.NumaDisable {
+   run := base
+   // Need to make a copy of this so that
+   // we have a pointer to use as a tristate
+   run.RunConfig.NumaDisable = new(bool)
+   *run.RunConfig.NumaDisable = d
+   if d {
+   run.Label = run.Label+" NumaOff"
+   } else {
+   run.Label = run.Label+" NumaOn "
+   }
+   b = append(b, run)
+   }
+   }
+   a = b
+   b = nil
+   }
+
for i := range a {
fmt.Printf("%s\n", a[i].Label)
}
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 48/59] libxl: Add Ctx.CheckOpen

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

To standardize the error in the case that Ctx isn't open.  Add checks to all 
functions
which call libxl functions directly.

Signed-off-by: George Dunlap 
---
 libxl.go | 48 +---
 1 file changed, 45 insertions(+), 3 deletions(-)

diff --git a/libxl.go b/libxl.go
index e73c06b..8f16b1d 100644
--- a/libxl.go
+++ b/libxl.go
@@ -164,9 +164,16 @@ func (Ctx *Context) Close() (err error) {
return
 }
 
-func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+func (Ctx *Context) CheckOpen() (err error) {
if Ctx.ctx == nil {
err = fmt.Errorf("Context not opened")
+   }
+   return
+}
+
+func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+   err = Ctx.CheckOpen()
+   if err != nil {
return
}
 
@@ -209,8 +216,8 @@ func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err 
error) {
 }
 
 func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
-   if Ctx.ctx == nil {
-   err = fmt.Errorf("Context not opened")
+   err = Ctx.CheckOpen()
+   if err != nil {
return
}
 
@@ -359,6 +366,11 @@ func SchedulerFromString(name string) (s Scheduler, err 
error) {
 // 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, )
@@ -394,6 +406,11 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
 // 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))
@@ -420,6 +437,11 @@ func (Ctx *Context) CpupoolCreate(Name string, Scheduler 
Scheduler, Cpumap Bitma
 
 // 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))
// FIXME: Proper error
if ret != 0 {
@@ -432,6 +454,11 @@ func (Ctx *Context) CpupoolDestroy(Poolid uint32) (err 
error) {
 
 // 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))
// FIXME: Proper error
if ret != 0 {
@@ -445,6 +472,11 @@ func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) 
(err error) {
 // 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()

@@ -460,6 +492,11 @@ func (Ctx *Context) CpupoolCpuaddCpumap(Poolid uint32, 
Cpumap Bitmap) (err error
 
 // 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))
// FIXME: Proper error
if ret != 0 {
@@ -473,6 +510,11 @@ func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu 
int) (err error) {
 // 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()

-- 
2.7.4


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


[Xen-devel] [PATCH RFC 39/59] libxl.go: Put common link flags in libxl.go

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

...so that the only things added in the makefile are extra flags
required when linking against non-installed builds.

Add in the text of the GPL while we're at it.

Signed-off-by: George Dunlap 
---
 Makefile |  3 +--
 libxl.go | 19 +++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 0e0b231..0265dc8 100644
--- a/Makefile
+++ b/Makefile
@@ -7,11 +7,10 @@ all: $(BIN)
 
 
 CGO_CFLAGS = -I/build/hg/xen.git/dist/install/usr/local/include
-CGO_LIBS = -lyajl -lxenlight
 
 # FIXME
 XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
-CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) $(CGO_LIBS)
+CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH)
 
 schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go plan.go
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
diff --git a/libxl.go b/libxl.go
index 9477bca..6621974 100644
--- a/libxl.go
+++ b/libxl.go
@@ -1,6 +1,25 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
 package main
 
 /*
+#cgo LDFLAGS: -lyajl -lxenlight
 #include 
 #include 
 */
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 49/59] libxl: Implement libxl_cpupool_info and Scheduler.FromString()

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Unify the libxl_cpupoolinfo -> CpupoolInfo translation in a function.

Also make bitmapCToGo pass-by-value rather than pass-by-reference,
since it only has two elements and doesn't need to be modified.

Signed-off-by: George Dunlap 
---
 libxl.go | 64 ++--
 1 file changed, 54 insertions(+), 10 deletions(-)

diff --git a/libxl.go b/libxl.go
index 8f16b1d..dfe4f40 100644
--- a/libxl.go
+++ b/libxl.go
@@ -234,7 +234,7 @@ func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
  */
 
 // Return a Go bitmap which is a copy of the referred C bitmap.
-func bitmapCToGo(cbm *C.libxl_bitmap) (gbm 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)
@@ -338,7 +338,6 @@ func (a Bitmap) And(b Bitmap) (c Bitmap) {
 }
 
 // const char *libxl_scheduler_to_string(libxl_scheduler p);
-// int libxl_scheduler_from_string(const char *s, libxl_scheduler *e);
 func (s Scheduler) String() (string) {
cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
// No need to free const return value
@@ -346,6 +345,32 @@ func (s Scheduler) String() (string) {
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, )
+   if ret != 0 {
+   err = fmt.Errorf("libxl_scheduler_from_string: %d\n", 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))
@@ -385,20 +410,37 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
cpupoolListSlice := (*[1 << 
30]C.libxl_cpupoolinfo)(unsafe.Pointer(c_cpupool_list))[:nbPool:nbPool]
 
for i := range cpupoolListSlice {
-   var info CpupoolInfo
+   info := translateCpupoolInfoCToGo(cpupoolListSlice[i])

-   info.Poolid = uint32(cpupoolListSlice[i].poolid)
-   info.PoolName = C.GoString(cpupoolListSlice[i].pool_name)
-   info.Scheduler = Scheduler(cpupoolListSlice[i].sched)
-   info.DomainCount = int(cpupoolListSlice[i].n_dom)
-   info.Cpumap = bitmapCToGo([i].cpumap)
-
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, _cpupool, C.uint32_t(Poolid))
+   if ret != 0 {
+   err = fmt.Errorf("libxl_cpupool_info failed: %d", ret)
+   return
+   }
+   defer C.libxl_cpupoolinfo_dispose(_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,
@@ -532,7 +574,6 @@ func (Ctx *Context) CpupoolCpuremoveCpumap(Poolid uint32, 
Cpumap Bitmap) (err er
 // 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);
-// int libxl_cpupool_info(libxl_ctx *ctx, libxl_cpupoolinfo *info, uint32_t 
poolid);
 
 //
 // Utility functions
@@ -615,5 +656,8 @@ func XlTest(Args []string) {
fmt.Printf("Pool id: %d\n", Poolid)
}
 
+   pool = Ctx.CpupoolInfo(0)
+   fmt.Printf("Cpupool 0 info: %v\n", pool)
+   
Ctx.Close()
 }
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 29/59] report: Add basic html report

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Use Google's chartapi to create a (mostly) self-contained html file.
Start with just scatterplots of the raw data for proof-of-concept.

Signed-off-by: George Dunlap 
---
 Makefile  |   2 +-
 benchmark.go  |   1 +
 htmlreport.go | 233 ++
 main.go   |  12 +++
 4 files changed, 247 insertions(+), 1 deletion(-)
 create mode 100644 htmlreport.go

diff --git a/Makefile b/Makefile
index 54f2ce8..c1b9ee4 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ CGO_LIBS = -lyajl -lxenlight
 XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
 CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) $(CGO_LIBS)
 
-schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go
+schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
 
 .PHONY: clean
diff --git a/benchmark.go b/benchmark.go
index de1f650..8be00a0 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -438,3 +438,4 @@ func (plan *BenchmarkPlan) TextReport(level int) (err 
error) {
 
return
 }
+
diff --git a/htmlreport.go b/htmlreport.go
new file mode 100644
index 000..6f61998
--- /dev/null
+++ b/htmlreport.go
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+package main
+
+import (
+   "fmt"
+   "os"
+   "io"
+   "encoding/json"
+)
+
+type OptionAxis struct {
+   Title string `json:"title"`
+   MinValue float64 `json:"minValue"`
+   MaxValue float64 `json:"maxValue"`
+}
+
+type Options struct {
+   Title string `json:"title"`
+   HAxis OptionAxis `json:"hAxis"`
+   VAxis OptionAxis `json:"vAxis"`
+   Legend string`json:"legend"`
+}
+
+type Point struct {
+   x float64
+   y float64
+}
+
+type RunRaw struct {
+   Label string
+   Points [][]Point
+}
+
+func (options *Options) OutputJavascript(w io.Writer, id int) (err error) {
+   var optionsJson []byte
+   optionsJson, err = json.Marshal(options)
+   if err != nil {
+   return
+   }
+
+   fmt.Fprintf(w, "var sp%dopt = ", id)
+   fmt.Fprint(w, string(optionsJson))
+   fmt.Fprintln(w, ";")
+
+   return
+}
+
+func (p *Point) OutputJson(w io.Writer, id int, max int) (err error) {
+   fmt.Fprintf(w, "[%f", p.x)
+   for i := 0; i < max; i++ {
+   if i == id {
+   fmt.Fprintf(w, ", %f", p.y)
+   } else {
+   fmt.Fprintf(w, ", null")
+   }
+   }
+   fmt.Fprint(w, "],\n")
+   return
+}
+
+func (d *RunRaw) OutputHTML(w io.Writer, run int) (err error) {
+   fmt.Fprintf(w, "\n", run)
+   return
+}
+
+func (d *RunRaw) OutputJavascript(w io.Writer, run int) (err error) {
+   var options Options
+
+   options.Title = fmt.Sprintf("Run %s (%d) Individual Throughput", 
d.Label, run)
+   options.HAxis.Title = "Time"
+   options.VAxis.Title = "Throughput"
+
+   var xmm MinMax
+   var ymm MinMax
+   for i := range d.Points {
+   for j := range d.Points[i] {
+   xmm.Update(d.Points[i][j].x)
+   ymm.Update(d.Points[i][j].y)
+   }
+   }
+
+   options.HAxis.MaxValue = xmm.Max
+   options.VAxis.MaxValue = ymm.Max
+
+   err = options.OutputJavascript(w, run)
+   if err != nil {
+   return
+   }
+
+   fmt.Printf("var sp%ddata = new 
google.visualization.DataTable();\n", run)
+   fmt.Printf("sp%ddata.addColumn('number', 'Time');\n", run)
+   for i := range d.Points {
+   fmt.Printf("sp%ddata.addColumn('number', 'Worker 
%d');\n", run, i)
+   }
+   fmt.Printf("sp%ddata.addRows([\n", run)
+
+   // Can't use json here because we need to be able to use 'null' for 
non-existent values
+   for i := range d.Points {
+   for j := range d.Points[i] {
+   err = d.Points[i][j].OutputJson(w, i, len(d.Points))
+   if err != nil {
+

[Xen-devel] [PATCH RFC 41/59] libxl.go: Link statically rather than dynamically

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Link statically rather than dynamically, because Go prefers that.

This also gets rid of the need for schedbench-report, so disable that
from the build (although keep the rule and the dummy file around just
in case.

Also update README.md.

Signed-off-by: George Dunlap 
---
 Makefile | 11 +++
 libxl.go | 10 +-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index 0265dc8..699cc53 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-BIN = schedbench schedbench-report
+BIN = schedbench
 BINALL = $(BIN)
 
 .PHONY: all
@@ -10,12 +10,15 @@ CGO_CFLAGS = 
-I/build/hg/xen.git/dist/install/usr/local/include
 
 # FIXME
 XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
-CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH)
+CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) 
 
 schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go plan.go
-   CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
+   CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build 
-ldflags '-linkmode external -extldflags "-static"' -o $@ $^
 
-# FIXME: Do with dlopen instead
+# If we use a statically linked binary we don't need this; the same
+# binary can be used on any system.  Keep this version (without any
+# run support) support) around for now in case we want to go back to
+# it.
 schedbench-report: main.go benchmark.go stubs.go htmlreport.go plan.go
go build -o $@ $^
 
diff --git a/libxl.go b/libxl.go
index 6621974..27e7766 100644
--- a/libxl.go
+++ b/libxl.go
@@ -19,12 +19,20 @@
 package main
 
 /*
-#cgo LDFLAGS: -lyajl -lxenlight
+#cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
-lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall -lz 
-luuid -lutil
 #include 
 #include 
 */
 import "C"
 
+/*
+ * Other flags that may be needed at some point: 
+ *  -lnl-route-3 -lnl-3
+ *
+ * To get back to simple dynamic linking:
+#cgo LDFLAGS: -lxenlight -lyajl
+*/
+
 import (
"unsafe"
"fmt"
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 46/59] libxl: Reorganize bitmapGotoC

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

No need to "allocate" the structure elsewhere; passing as a return
value makes usage a lot cleaner.

Signed-off-by: George Dunlap 
---
 libxl.go | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/libxl.go b/libxl.go
index 92064ca..16f4645 100644
--- a/libxl.go
+++ b/libxl.go
@@ -191,8 +191,8 @@ func bitmapCToGo(cbm *C.libxl_bitmap) (gbm Bitmap) {
 }
 
 // Must be C.libxl_bitmap_dispose'd of afterwards
-func bitmapGotoC(gbm Bitmap, cbm *C.libxl_bitmap) {
-   C.libxl_bitmap_init(cbm)
+func bitmapGotoC(gbm Bitmap) (cbm C.libxl_bitmap) {
+   C.libxl_bitmap_init()
 
size := len(gbm.bitmap)
cbm._map = (*C.uint8_t)(C.malloc(C.size_t(size)))
@@ -206,6 +206,8 @@ func bitmapGotoC(gbm Bitmap, cbm *C.libxl_bitmap) {
 
// And copy the Go array into the C array
copy(mapslice, gbm.bitmap)
+
+   return
 }
 
 func (bm *Bitmap) Test(bit int) (bool) {
@@ -385,8 +387,7 @@ func (Ctx *Context) CpupoolCreate(Name string, Scheduler 
Scheduler, Cpumap Bitma
var uuid C.libxl_uuid
C.libxl_uuid_generate()
 
-   var cbm C.libxl_bitmap
-   bitmapGotoC(Cpumap, )
+   cbm := bitmapGotoC(Cpumap)
defer C.libxl_bitmap_dispose()

ret := C.libxl_cpupool_create(Ctx.ctx, name, 
C.libxl_scheduler(Scheduler),
@@ -429,8 +430,7 @@ func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) 
(err error) {
 // 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) {
-   var cbm C.libxl_bitmap
-   bitmapGotoC(Cpumap, )
+   cbm := bitmapGotoC(Cpumap)
defer C.libxl_bitmap_dispose()

ret := C.libxl_cpupool_cpuadd_cpumap(Ctx.ctx, C.uint32_t(Poolid), )
@@ -458,8 +458,7 @@ func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu 
int) (err error) {
 // 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) {
-   var cbm C.libxl_bitmap
-   bitmapGotoC(Cpumap, )
+   cbm := bitmapGotoC(Cpumap)
defer C.libxl_bitmap_dispose()

ret := C.libxl_cpupool_cpuremove_cpumap(Ctx.ctx, C.uint32_t(Poolid), 
)
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 34/59] controller: Make a useful config file

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Allow a simple "skeleton" config file which can be adapted for the
particular use case.  Have 'plan' expand this with the real benchmark
plan.

Include "sample.bench" as a template to modify.  Also update the
README.md accordingly.

Signed-off-by: George Dunlap 
---
 Makefile |  4 +--
 benchmark.go |  9 ---
 main.go  | 48 ++--
 plan.go  | 79 
 4 files changed, 93 insertions(+), 47 deletions(-)
 create mode 100644 plan.go

diff --git a/Makefile b/Makefile
index 6dee499..af55e0a 100644
--- a/Makefile
+++ b/Makefile
@@ -13,11 +13,11 @@ CGO_LIBS = -lyajl -lxenlight
 XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
 CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) $(CGO_LIBS)
 
-schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go
+schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go plan.go
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
 
 # FIXME: Do with dlopen instead
-schedbench-report: main.go processworker.go xenworker_dummy.go benchmark.go 
run.go htmlreport.go
+schedbench-report: main.go processworker.go xenworker_dummy.go benchmark.go 
run.go htmlreport.go plan.go
go build -o $@ $^
 
 .PHONY: clean
diff --git a/benchmark.go b/benchmark.go
index 8be00a0..31b3711 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -148,12 +148,13 @@ type BenchmarkRun struct {
 }
 
 type BenchmarkPlan struct {
-   filename string
-   WorkerType int
+   Input *PlanInput `json:",omitempty"`
+   filename string  `json:",omitempty"`
+   WorkerType int   `json:",omitempty"`
// Global options for workers that will be over-ridden by Run
// and WorkerSet config options
-   WorkerConfig
-   Runs []BenchmarkRun
+   WorkerConfig `json:",omitempty"`
+   Runs []BenchmarkRun  `json:",omitempty"`
 }
 
 func (run *BenchmarkRun) checkSummary() (done bool, err error) {
diff --git a/main.go b/main.go
index 2aa8bae..059a54a 100644
--- a/main.go
+++ b/main.go
@@ -49,49 +49,15 @@ func main() {
verbosity, _ = strconv.Atoi(Args[1])
Args = Args[2:]
case "plan":
-   workerA := []string{"burnwait", "70", "20"}
-   //workerB := []string{"burnwait", "10", "2000"}
-   workerB := []string{"burnwait", "10", "30",
-   "burnwait", "20", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "30", "30",
-   }
-   
-   
-   plan :=  BenchmarkPlan{
-   WorkerType:WorkerXen,
-   WorkerConfig:WorkerConfig{Pool:"schedbench"},
-   filename:filename,
-   Runs:[]BenchmarkRun{
-   {Label:"baseline-a",
-   WorkerSets:[]WorkerSet{
-   
{Params:WorkerParams{workerA},
-   Count:1}},
-   RuntimeSeconds:10,},
-   {Label:"baseline-b",
-   WorkerSets:[]WorkerSet{
-   
{Params:WorkerParams{workerB},
-   Count:1}},
-   RuntimeSeconds:10,},
-   }}
-   
-   for i := 1; i <= 16 ; i *= 2 {
-   label := fmt.Sprintf("%da+%db", i, i)
-   run := BenchmarkRun{
-   Label:label,
-   WorkerSets:[]WorkerSet{
-   {Params:WorkerParams{workerA},
-   Count:i},
-   {Params:WorkerParams{workerB},
-   Count:i}},
-   RuntimeSeconds:10}
-   plan.Runs = append(plan.Runs, run)
+   plan, err := LoadBenchmark(filename)
+   if err != nil {
+   

[Xen-devel] [PATCH RFC 42/59] plan: Allow "templating" from other runs

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Allow 'plan' to use an existing run as a "template": load the template,
discard the runs, and save the result in the new file.

Use like this:

./schedbench -t 18.bench -f 20.bench plan

This will make 20 with an empty plan identical to that in 18.

Signed-off-by: George Dunlap 
---
 main.go | 38 +-
 plan.go | 32 ++--
 2 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/main.go b/main.go
index 8cbd708..ead6ab0 100644
--- a/main.go
+++ b/main.go
@@ -30,6 +30,7 @@ func main() {
 
Args = Args[1:]
filename := "test.bench"
+   template := ""
verbosity := 0
 
for len(Args) > 0 {
@@ -41,6 +42,13 @@ func main() {
}
filename = Args[1]
Args = Args[2:]
+   case "-t":
+   if len(Args) < 2 {
+   fmt.Println("Need arg for -t")
+   os.Exit(1)
+   }
+   template = Args[1]
+   Args = Args[2:]
case "-v":
if len(Args) < 2 {
fmt.Println("Need arg for -v")
@@ -49,20 +57,40 @@ func main() {
verbosity, _ = strconv.Atoi(Args[1])
Args = Args[2:]
case "plan":
-   plan, err := LoadBenchmark(filename)
+   // Load either the template benchmark or the filename
+   loadfile := filename
+   if template != "" {
+   loadfile = template
+   }
+   plan, err := LoadBenchmark(loadfile)
if err != nil {
-   fmt.Println("Loading benchmark ", filename, " 
", err)
+   fmt.Printf("Loading benchmark %s: %v\n",
+   loadfile, err)
os.Exit(1)
}
+
+   if template != "" {
+   plan.filename = filename
+   err = plan.ClearRuns()
+   if err != nil {
+   fmt.Printf("Clearing runs: %v\n",
+   err)
+   os.Exit(1)
+   }
+   }

-   plan.ExpandInput()
+   err = plan.ExpandInput()
+   if err != nil {
+   fmt.Printf("Expanding plan: %v\n", err)
+   os.Exit(1)
+   }
 
err = plan.Save()
if err != nil {
-   fmt.Println("Saving plan ", filename, " ", err)
+   fmt.Printf("Saving plan %s: %v\n", filename, 
err)
os.Exit(1)
}
-   fmt.Println("Created plan in ", filename)
+   fmt.Printf("Created plan in %s\n", filename)
Args = Args[1:]
case "run":
plan, err := LoadBenchmark(filename)
diff --git a/plan.go b/plan.go
index 24c6bd4..e535603 100644
--- a/plan.go
+++ b/plan.go
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
 package main
 
 import (
@@ -19,15 +37,25 @@ var WorkerPresets = map[string]WorkerParams{
"P001":WorkerParams{[]string{"burnwait", "70", "20"}},
 }
 
+func (plan *BenchmarkPlan) ClearRuns() (err error) {
+   plan.Runs = nil
+
+   return
+}
 
 func (plan *BenchmarkPlan) ExpandInput() (err error) {
if plan.Runs != nil {
-   fmt.Printf("plan.Expand: Runs non-empty, not doing anything\n");
+   err = fmt.Errorf("Runs non-empty, not doing anything\n");
+   return
+   }
+
+   if plan.Input == nil {
+   err = fmt.Errorf("Input nil, 

[Xen-devel] [PATCH RFC 47/59] libxl: Reorganize code

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Put all type and enumeration definitions at the top of the file,
separated into "builtins" and "idl-generated".

Also define Uuid as C.libxl_uud.  (Not sure if this gives us the
functionality we need without having to manually copy things in.)

Finally, get rid of Bitmap.Alloc().  It's redundant now that
Bitmap.Set() automatically extends the array.

Signed-off-by: George Dunlap 
---
 libxl.go | 189 ++-
 1 file changed, 102 insertions(+), 87 deletions(-)

diff --git a/libxl.go b/libxl.go
index 16f4645..e73c06b 100644
--- a/libxl.go
+++ b/libxl.go
@@ -39,10 +39,102 @@ import (
"time"
 )
 
+/*
+ * Types: Builtins
+ */
+
+type Domid uint32
+
+type MemKB uint64
+
+// 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
+}
+
 type Context struct {
ctx *C.libxl_ctx
 }
 
+type Uuid C.libxl_uuid
+
+/*
+ * Types: IDL
+ * 
+ * FIXME: Generate these automatically from the IDL
+ */
+type Dominfo struct {
+   Uuid  Uuid
+   Domid Domid
+   Running   bool
+   Blocked   bool
+   Pausedbool
+   Shutdown  bool
+   Dying bool
+   Never_stopbool
+   
+   Shutdown_reason   int32 // FIXME shutdown_reason enumeration
+   Outstanding_memkb MemKB
+   Current_memkb MemKB
+   Shared_memkb  MemKB
+   Paged_memkb   MemKB
+   Max_memkb MemKB
+   Cpu_time  time.Duration
+   Vcpu_max_id   uint32
+   Vcpu_online   uint32
+   Cpupool   uint32
+   Domain_type   int32 //FIXME libxl_domain_type enumeration
+
+}
+
+// # 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
+)
+
+// 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
+}
+
+/*
+ * Context
+ */
 var Ctx Context
 
 func (Ctx *Context) IsOpen() bool {
@@ -72,43 +164,12 @@ func (Ctx *Context) Close() (err error) {
return
 }
 
-// Builtins
-type Domid uint32
-
-type MemKB uint64
-
-// FIXME: Use the idl to generate types
-type Dominfo struct {
-   // FIXME: uuid
-   Domid Domid
-   Running   bool
-   Blocked   bool
-   Pausedbool
-   Shutdown  bool
-   Dying bool
-   Never_stopbool
-   
-   Shutdown_reason   int32 // FIXME shutdown_reason enumeration
-   Outstanding_memkb MemKB
-   Current_memkb MemKB
-   Shared_memkb  MemKB
-   Paged_memkb   MemKB
-   Max_memkb MemKB
-   Cpu_time  time.Duration
-   Vcpu_max_id   uint32
-   Vcpu_online   uint32
-   Cpupool   uint32
-   Domain_type   int32 //FIXME libxl_domain_type enumeration
-
-}
-
 func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
if Ctx.ctx == nil {
err = fmt.Errorf("Context not opened")
return
}
 
-   
var cdi C.libxl_dominfo
 
ret := C.libxl_domain_info(Ctx.ctx, unsafe.Pointer(), 
C.uint32_t(Id))
@@ -119,8 +180,12 @@ func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err 
error) {
return
}
 
-   // FIXME -- use introspection to make this more robust
+   // We could consider having this boilerplate generated by the
+   // idl, in a function like this:
+   //
+   // di = translateCdomaininfoToGoDomaininfo(cdi)
di = {}
+   di.Uuid = Uuid(cdi.uuid)
di.Domid 

[Xen-devel] [PATCH RFC 28/59] controller: Handle worker early death

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Log raw worker output.  In the event of an unexpected worker death,
dump the output and stop further processing.

Also fix an assert that caused workers to die if the timer was too
exact.

Signed-off-by: George Dunlap 
---
 benchmark.go |  7 ---
 processworker.go | 18 --
 run.go   | 24 ++--
 xenworker.go | 21 +++--
 4 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 5e35997..de1f650 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -74,13 +74,6 @@ type WorkerSet struct {
Count int
 }
 
-type Worker interface {
-   SetId(WorkerId)
-   Init(WorkerParams, WorkerConfig) error
-   Shutdown()
-   Process(chan WorkerReport, chan bool)
-}
-
 const (
USEC = 1000
MSEC = USEC * 1000
diff --git a/processworker.go b/processworker.go
index f517321..999e76a 100644
--- a/processworker.go
+++ b/processworker.go
@@ -32,6 +32,7 @@ type ProcessWorker struct {
c *exec.Cmd
stdout io.ReadCloser
jsonStarted bool
+   Log []string
 }
 
 func (w *ProcessWorker) SetId(i WorkerId) {
@@ -54,7 +55,19 @@ func (w *ProcessWorker) Shutdown() {
w.c.Process.Kill()
 }
 
-func (w *ProcessWorker) Process(report chan WorkerReport, done chan bool) {
+func (w *ProcessWorker) DumpLog(f io.Writer) (err error) {
+   b := bufio.NewWriter(f)
+   defer b.Flush()
+   for _, line := range w.Log {
+   _, err = fmt.Println(b, line)
+   if err != nil {
+   return
+   }
+   }
+   return
+}
+
+func (w *ProcessWorker) Process(report chan WorkerReport, done chan WorkerId) {
w.c.Start()
 
scanner := bufio.NewScanner(w.stdout)
@@ -63,6 +76,7 @@ func (w *ProcessWorker) Process(report chan WorkerReport, 
done chan bool) {
s := scanner.Text()

//fmt.Println("Got these bytes: ", s);
+   w.Log = append(w.Log, s)
 
if w.jsonStarted {
var r WorkerReport
@@ -77,7 +91,7 @@ func (w *ProcessWorker) Process(report chan WorkerReport, 
done chan bool) {
}
}
 
-   done <- true
+   done <- w.id
 
w.c.Wait()
 }
diff --git a/run.go b/run.go
index ed1957b..1b39730 100644
--- a/run.go
+++ b/run.go
@@ -26,6 +26,7 @@ import (
"regexp"
"strconv"
"bufio"
+   "io"
 )
 
 type WorkerState struct {
@@ -33,6 +34,14 @@ type WorkerState struct {
LastReport WorkerReport
 }
 
+type Worker interface {
+   SetId(WorkerId)
+   Init(WorkerParams, WorkerConfig) error
+   Shutdown()
+   Process(chan WorkerReport, chan WorkerId)
+   DumpLog(io.Writer) error
+}
+
 func Report(ws *WorkerState, r WorkerReport) {
//fmt.Println(r)
 
@@ -57,7 +66,7 @@ func Report(ws *WorkerState, r WorkerReport) {
 
 type WorkerList map[WorkerId]*WorkerState
 
-func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
+func (ws *WorkerList) Start(report chan WorkerReport, done chan WorkerId) (i 
int) {
i = 0
for j := range *ws {
go (*ws)[j].w.Process(report, done)
@@ -160,7 +169,7 @@ func (run *BenchmarkRun) Run() (err error) {
}

report := make(chan WorkerReport)
-   done := make(chan bool)
+   done := make(chan WorkerId)
signals := make(chan os.Signal, 1)
 
signal.Notify(signals, os.Interrupt)
@@ -179,12 +188,16 @@ func (run *BenchmarkRun) Run() (err error) {
run.Results.Raw = append(run.Results.Raw, r)
Report(Workers[r.Id], r)
}
-   case <-done:
+   case did := <-done:
if ! stopped {
-   fmt.Println("WARNING: Worker left early")
+   fmt.Println("WARNING: Worker", did, "left 
early, shutting down workers")
+   Workers.Stop()
+   stopped = true
+   err = fmt.Errorf("Worker %v exited early", did)
+   Workers[did].w.DumpLog(os.Stdout)
}
i--;
-   fmt.Println(i, "workers left");
+   fmt.Printf("Worker %v exited; %d workers left\n", did, 
i);
case <-timeout:
if ! stopped {
Workers.Stop()
@@ -201,7 +214,6 @@ func (run *BenchmarkRun) Run() (err error) {
}
err = fmt.Errorf("Interrupted")
} else {
-   err = fmt.Errorf("Interrupted")
fmt.Println("SIGINT received after stop, 

[Xen-devel] [PATCH RFC 30/59] htmlreport: Include utilization scatterplots

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Reformat RunRaw so that it's a more generic scatterplot, with the
caller specifying the javascript tag, title, and axes.  Keep them as a
straight list to be displayed rather than defining them on a per-run
basis.

Collect a slice of utilization points at the same time as collecting
the throughput metrics, add them both at the same time.

While we're here, add "omitempty" to some of the options so no json is
generated if nothing is specified.  Leave "MinValue" so that we are
able to specify a zero origin (which will also be the default).

Finally, don't bother finding minimum and maximum points; the chart
plotter will do that anyway.

Signed-off-by: George Dunlap 
---
 htmlreport.go | 89 +++
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/htmlreport.go b/htmlreport.go
index 6f61998..545582d 100644
--- a/htmlreport.go
+++ b/htmlreport.go
@@ -26,16 +26,17 @@ import (
 )
 
 type OptionAxis struct {
-   Title string `json:"title"`
+   Title string `json:"title,omitempty"`
+   // Always include this one so that we can start graphs at 0
MinValue float64 `json:"minValue"`
-   MaxValue float64 `json:"maxValue"`
+   MaxValue float64 `json:"maxValue,omitempty"`
 }
 
 type Options struct {
-   Title string `json:"title"`
+   Title string `json:"title,omitempty"`
HAxis OptionAxis `json:"hAxis"`
VAxis OptionAxis `json:"vAxis"`
-   Legend string`json:"legend"`
+   Legend string`json:"legend,omitempty"`
 }
 
 type Point struct {
@@ -44,18 +45,21 @@ type Point struct {
 }
 
 type RunRaw struct {
-   Label string
+   Tag string
+   Title string
+   hTitle string
+   vTitle string
Points [][]Point
 }
 
-func (options *Options) OutputJavascript(w io.Writer, id int) (err error) {
+func (options *Options) OutputJavascript(w io.Writer, tag string) (err error) {
var optionsJson []byte
optionsJson, err = json.Marshal(options)
if err != nil {
return
}
 
-   fmt.Fprintf(w, "var sp%dopt = ", id)
+   fmt.Fprintf(w, "var %sopt = ", tag)
fmt.Fprint(w, string(optionsJson))
fmt.Fprintln(w, ";")
 
@@ -75,41 +79,29 @@ func (p *Point) OutputJson(w io.Writer, id int, max int) 
(err error) {
return
 }
 
-func (d *RunRaw) OutputHTML(w io.Writer, run int) (err error) {
-   fmt.Fprintf(w, "\n", run)
+func (d *RunRaw) OutputHTML(w io.Writer) (err error) {
+   fmt.Fprintf(w, "\n", d.Tag)
return
 }
 
-func (d *RunRaw) OutputJavascript(w io.Writer, run int) (err error) {
+func (d *RunRaw) OutputJavascript(w io.Writer) (err error) {
var options Options
 
-   options.Title = fmt.Sprintf("Run %s (%d) Individual Throughput", 
d.Label, run)
-   options.HAxis.Title = "Time"
-   options.VAxis.Title = "Throughput"
+   options.Title = d.Title
+   options.HAxis.Title = d.hTitle
+   options.VAxis.Title = d.vTitle
 
-   var xmm MinMax
-   var ymm MinMax
-   for i := range d.Points {
-   for j := range d.Points[i] {
-   xmm.Update(d.Points[i][j].x)
-   ymm.Update(d.Points[i][j].y)
-   }
-   }
-
-   options.HAxis.MaxValue = xmm.Max
-   options.VAxis.MaxValue = ymm.Max
-
-   err = options.OutputJavascript(w, run)
+   err = options.OutputJavascript(w, d.Tag)
if err != nil {
return
}
 
-   fmt.Printf("var sp%ddata = new 
google.visualization.DataTable();\n", run)
-   fmt.Printf("sp%ddata.addColumn('number', 'Time');\n", run)
+   fmt.Printf("var %sdata = new 
google.visualization.DataTable();\n", d.Tag)
+   fmt.Printf("%sdata.addColumn('number', 'Time');\n", d.Tag)
for i := range d.Points {
-   fmt.Printf("sp%ddata.addColumn('number', 'Worker 
%d');\n", run, i)
+   fmt.Printf("%sdata.addColumn('number', 'Worker 
%d');\n", d.Tag, i)
}
-   fmt.Printf("sp%ddata.addRows([\n", run)
+   fmt.Printf("%sdata.addRows([\n", d.Tag)
 
// Can't use json here because we need to be able to use 'null' for 
non-existent values
for i := range d.Points {
@@ -122,8 +114,8 @@ func (d *RunRaw) OutputJavascript(w io.Writer, run int) 
(err error) {
}
fmt.Print("  ]);\n")

-   fmt.Printf("var sp%dchart = new 
google.visualization.ScatterChart(document.getElementById('scatterplot%d'));\n",
 run, run);
-   fmt.Printf("sp%dchart.draw(sp%ddata, sp%dopt);\n\n", run, run, 
run)
+   fmt.Printf("var %schart = new 
google.visualization.ScatterChart(document.getElementById('scatterplot%s'));\n",
 d.Tag, d.Tag);
+   fmt.Printf("%schart.draw(%sdata, %sopt);\n\n", 

[Xen-devel] [PATCH RFC 55/59] plan: Make the matrix generation more programmatic

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Rather than have nested loops, keep a running list of all the configs
we've created so far.  Then for each existing new element of the
matrix, combine it with all the existing columns.

Signed-off-by: George Dunlap 
---
 plan.go | 50 +++---
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/plan.go b/plan.go
index e535603..736d9f3 100644
--- a/plan.go
+++ b/plan.go
@@ -72,7 +72,9 @@ func (plan *BenchmarkPlan) ExpandInput() (err error) {
schedulers = append(schedulers, "")
}
 
-   // Always do the baselines
+   // Start by making a slice with baselines and each of the counts
+   var a, b []BenchmarkRun
+   
for _, wn := range plan.Input.SimpleMatrix.Workers {
wp := WorkerPresets[wn]

@@ -85,39 +87,49 @@ func (plan *BenchmarkPlan) ExpandInput() (err error) {
WorkerSets:[]WorkerSet{{Params:wp, Count:1}},
RuntimeSeconds:10,
}
-   
-   for _, s := range schedulers {
-   fmt.Printf("Making baseline %s run, sched %s\n", wn, s)
-   run.RunConfig.Scheduler = s
-   run.Label = wn+" baseline "+s
-   plan.Runs = append(plan.Runs, run)
-   }
+
+   run.Label = wn+" baseline"
+   a = append(a, run)
}
-   
+
+
for _, c := range plan.Input.SimpleMatrix.Count {
run := BenchmarkRun{
RuntimeSeconds:10,
}

-   var label string
for _, wn := range plan.Input.SimpleMatrix.Workers {
wp := WorkerPresets[wn]

-   if label != "" {
-   label = label+" + "
+   if run.Label != "" {
+   run.Label = run.Label+" + "
}
-   label = fmt.Sprintf("%s%s %d ", label, wn, c)
-   
+   run.Label = fmt.Sprintf("%s%s %d", run.Label, wn, c)
+
ws := WorkerSet{Params:wp, Count:c}
run.WorkerSets = append(run.WorkerSets, ws)
}
-   for _, s := range schedulers {
-   fmt.Printf("Making count %d run, sched %s\n", c, s)
-   run.RunConfig.Scheduler = s
-   run.Label = label+s
-   plan.Runs = append(plan.Runs, run)
+
+   a = append(a, run)
+   }
+
+   // ...then cross it by schedulers
+   if len(schedulers) > 0 {
+   for _, base := range a {
+   for _, s := range schedulers {
+   run := base
+   run.RunConfig.Scheduler = s
+   run.Label = run.Label+" "+s
+   b = append(b, run)
+   }
}
+   a = b
+   b = nil
}
 
+   for i := range a {
+   fmt.Printf("%s\n", a[i].Label)
+   }
+   plan.Runs = a;
return
 }
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 50/59] libxl: Fix Bitmap.Max(), make Test() / Clear() more robust

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Bitmap.Max() should return the largest currently addressable bit; at the
moment it returns the total number of bits (which is one greater than
the largest addressable bit).

This also implicitly fixes a bug in Test() and Clear() which would cause
an out-of-range error when testing a bit equal to Max().

While we're here, allow Test() and Clear() to handle null bitmaps, the
same way Set() can.

Signed-off-by: George Dunlap 
---
 libxl.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libxl.go b/libxl.go
index dfe4f40..bfcaf0d 100644
--- a/libxl.go
+++ b/libxl.go
@@ -270,7 +270,7 @@ func bitmapGotoC(gbm Bitmap) (cbm C.libxl_bitmap) {
 
 func (bm *Bitmap) Test(bit int) (bool) {
ubit := uint(bit)
-   if (bit > bm.Max()) {
+   if (bit > bm.Max() || bm.bitmap == nil) {
return false
}

@@ -294,7 +294,7 @@ func (bm *Bitmap) SetRange(start int, end int) {
 
 func (bm *Bitmap) Clear(bit int) {
ubit := uint(bit)
-   if (bit > bm.Max()) {
+   if (bit > bm.Max() || bm.bitmap == nil) {
return
}

@@ -308,7 +308,7 @@ func (bm *Bitmap) ClearRange(start int, end int) {
 }
 
 func (bm *Bitmap) Max() (int) {
-   return len(bm.bitmap) * 8
+   return len(bm.bitmap) * 8 - 1
 }
 
 func (bm *Bitmap) IsEmpty() (bool) {
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 16/59] controller: Rename an element in BenchmarkRun to be more accurate

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 benchmark.go | 6 +++---
 main.go  | 6 +++---
 run.go   | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 2e03fe5..aaa4c98 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -84,7 +84,7 @@ type BenchmarkRunData struct {
 
 type BenchmarkRun struct {
Label string
-   Workers []WorkerSet
+   WorkerSets []WorkerSet
RuntimeSeconds int
Completed bool
Results BenchmarkRunData 
@@ -168,8 +168,8 @@ func (run *BenchmarkRun) TextReport() (err error) {
fmt.Printf("== RUN %s ==", run.Label)
 
wStart := 0
-   for i := range run.Workers {
-   ws := [i]
+   for i := range run.WorkerSets {
+   ws := [i]
n := ws.Count
params := ""
for _, s := range ws.Params.Args {
diff --git a/main.go b/main.go
index ebf990f..f58068f 100644
--- a/main.go
+++ b/main.go
@@ -46,12 +46,12 @@ func main() {
filename:filename,
Runs:[]BenchmarkRun{
{Label:"baseline-a",
-   Workers:[]WorkerSet{
+   WorkerSets:[]WorkerSet{
{Params:WorkerParams{workerA},
Count:1}},
RuntimeSeconds:10,},
{Label:"baseline-b",
-   Workers:[]WorkerSet{
+   WorkerSets:[]WorkerSet{
{Params:WorkerParams{workerB},
Count:1}},
RuntimeSeconds:10,},
@@ -62,7 +62,7 @@ func main() {
label := fmt.Sprintf("%da+%db", i, i)
run := BenchmarkRun{
Label:label,
-   Workers:[]WorkerSet{
+   WorkerSets:[]WorkerSet{
{Params:WorkerParams{workerA},
Count:i},
{Params:WorkerParams{workerB},
diff --git a/run.go b/run.go
index 7b5ef0a..762b408 100644
--- a/run.go
+++ b/run.go
@@ -105,7 +105,7 @@ func NewWorkerList(WorkerSets []WorkerSet, workerType int) 
(wl WorkerList, err e
 }
 
 func (run *BenchmarkRun) Run() (err error) {
-   Workers, err := NewWorkerList(run.Workers, WorkerXen)
+   Workers, err := NewWorkerList(run.WorkerSets, WorkerXen)
if err != nil {
fmt.Println("Error creating workers: %v", err)
return
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 31/59] Make a binary that can run reports on a system without libxl

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

To simplify report-generation and iteration, make a binary that
doesn't link against libxl.  Create a "dummy" Xen library that just
returns errors and warnings.

A better way to do this is probably to do some dlopen hackery (so we
can use the same binary), but that's for another day.

Signed-off-by: George Dunlap 
---
 Makefile   |  6 +-
 xenworker_dummy.go | 54 ++
 2 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 xenworker_dummy.go

diff --git a/Makefile b/Makefile
index c1b9ee4..6dee499 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-BIN = schedbench
+BIN = schedbench schedbench-report
 BINALL = $(BIN)
 
 .PHONY: all
@@ -16,6 +16,10 @@ CGO_LDFLAGS = -L$(XENLIB_PATH) 
-Wl,-rpath-link=$(XENLIB_PATH) $(CGO_LIBS)
 schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
 
+# FIXME: Do with dlopen instead
+schedbench-report: main.go processworker.go xenworker_dummy.go benchmark.go 
run.go htmlreport.go
+   go build -o $@ $^
+
 .PHONY: clean
 clean:
rm -f $(BINALL)
diff --git a/xenworker_dummy.go b/xenworker_dummy.go
new file mode 100644
index 000..02e90ce
--- /dev/null
+++ b/xenworker_dummy.go
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+package main
+
+import (
+   "fmt"
+   "io"
+)
+
+type XenWorker struct {
+}
+
+func (w *XenWorker) SetId(i WorkerId) {
+}
+
+func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) (err error) {
+   err = fmt.Errorf("Xen functionality not implemented");
+   return
+}
+
+// FIXME: Return an error
+func (w *XenWorker) Shutdown() {
+   
+   return
+}
+
+func (w *XenWorker) DumpLog(f io.Writer) (err error) {
+   err = fmt.Errorf("Xen functionality not implemented");
+   return
+}
+
+
+
+// FIXME: Return an error
+func (w *XenWorker) Process(report chan WorkerReport, done chan WorkerId) {
+   return;
+}
+
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 58/59] remove irrelevant files from old repository

2016-12-28 Thread Ronald Rojas
Signed-off-by: Ronald Rojas <ronlad...@gmail.com>
---
 Makefile   |  31 --
 benchmark.go   | 467 --
 htmlreport.go  | 238 --
 libxl.go   | 720 -
 main.go| 146 -
 plan.go| 157 -
 processworker.go   |  98 --
 run.go | 456 --
 stubs.go   |  34 --
 tools/golang/xenlight/libxl.go | 720 +
 xenworker.go   | 278 
 11 files changed, 720 insertions(+), 2625 deletions(-)
 delete mode 100644 Makefile
 delete mode 100644 benchmark.go
 delete mode 100644 htmlreport.go
 delete mode 100644 libxl.go
 delete mode 100644 main.go
 delete mode 100644 plan.go
 delete mode 100644 processworker.go
 delete mode 100644 run.go
 delete mode 100644 stubs.go
 create mode 100644 tools/golang/xenlight/libxl.go
 delete mode 100644 xenworker.go

diff --git a/Makefile b/Makefile
deleted file mode 100644
index 699cc53..000
--- a/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-BIN = schedbench
-BINALL = $(BIN)
-
-.PHONY: all
-all: $(BIN)
-
-
-
-CGO_CFLAGS = -I/build/hg/xen.git/dist/install/usr/local/include
-
-# FIXME
-XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
-CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) 
-
-schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go 
htmlreport.go plan.go
-   CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build 
-ldflags '-linkmode external -extldflags "-static"' -o $@ $^
-
-# If we use a statically linked binary we don't need this; the same
-# binary can be used on any system.  Keep this version (without any
-# run support) support) around for now in case we want to go back to
-# it.
-schedbench-report: main.go benchmark.go stubs.go htmlreport.go plan.go
-   go build -o $@ $^
-
-.PHONY: clean
-clean:
-   rm -f $(BINALL)
-
-.PHONY: dist
-dist:
-   cp $(BIN) $(DISTDIR)
diff --git a/benchmark.go b/benchmark.go
deleted file mode 100644
index abe2dfb..000
--- a/benchmark.go
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of the
- * License only.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-package main
-
-import (
-   "fmt"
-   "os"
-   "io/ioutil"
-   "encoding/json"
-   "math"
-   "time"
-)
-
-type WorkerId struct {
-   Set int
-   Id int
-}
-
-func (wid WorkerId) String() (string) {
-   return fmt.Sprintf("%d:%d", wid.Set, wid.Id)
-}
-
-type WorkerReport struct {
-   Id WorkerId
-   Now int
-   Kops int
-   MaxDelta int
-   Cputime time.Duration
-}
-
-type WorkerParams struct {
-   Args []string
-}
-
-func (l *WorkerParams) SetkHZ(kHZ uint64) {
-   if l.Args[0] == "kHZ" {
-   l.Args[1] = fmt.Sprintf("%d", kHZ)
-   } else {
-   l.Args = append([]string{"kHZ", fmt.Sprintf("%d", kHZ)}, 
l.Args...)
-   }
-}
-
-type WorkerConfig struct {
-   Pool string
-   SoftAffinity string
-}
-
-// Propagate unset values from a higher level
-func (l *WorkerConfig) PropagateFrom(g WorkerConfig) {
-   if l.Pool == "" {
-   l.Pool = g.Pool
-   }
-}
-
-type WorkerSet struct {
-   Params WorkerParams
-   Config WorkerConfig
-   Count int
-}
-
-const (
-   USEC = 1000
-   MSEC = USEC * 1000
-   SEC = MSEC * 1000
-)
-
-func Throughput(lt int, lm int, t int, m int) (tput float64) {
-   time := float64(t - lt) / SEC
-   kops := m - lm
-   
-   tput = float64(kops) / time
-   return
-}
-
-func Utilization(lt int, lct time.Duration, t int, ct time.Duration) (util 
float64) {
-   util = float64(ct - lct) / float64(t - lt)
-   return
-}
-
-type MinMax struct {
-   Min float64
-   Max float64
-}
-
-func (mm *MinMax) Update(x float64) {
-   if x > mm.Max {
-   mm.Max = x
-   }
-   if x < mm.Min || mm.Min == 0 {
-   mm.Min = x
-   }
-}
-

[Xen-devel] [PATCH RFC 43/59] libxl: Add bitmap support

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Make the structure compatible so that we can just copy things out or
in.

Use it to complete the Cpupool structure.

Signed-off-by: George Dunlap 
---
 libxl.go | 104 +++
 1 file changed, 98 insertions(+), 6 deletions(-)

diff --git a/libxl.go b/libxl.go
index 27e7766..3f6ba01 100644
--- a/libxl.go
+++ b/libxl.go
@@ -20,8 +20,8 @@ package main
 
 /*
 #cgo LDFLAGS: -lxenlight -lyajl_s -lxengnttab -lxenstore -lxenguest 
-lxentoollog -lxenevtchn -lxenctrl -lblktapctl -lxenforeignmemory -lxencall -lz 
-luuid -lutil
-#include 
 #include 
+#include 
 */
 import "C"
 
@@ -72,6 +72,7 @@ func (Ctx *Context) Close() (err error) {
return
 }
 
+// Builtins
 type Domid uint32
 
 type MemKB uint64
@@ -160,8 +161,66 @@ func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
 // uint32_t size;  /* number of bytes in map */
 // uint8_t *map;
 // } libxl_bitmap;
-// void libxl_bitmap_init(libxl_bitmap *map);
-// void libxl_bitmap_dispose(libxl_bitmap *map);
+
+// 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
+}
+
+func (bm *Bitmap) Alloc(max int) {
+   bm.bitmap = make([]C.uint8_t, (max + 7) / 8)
+}
+
+// Return a Go bitmap which is a copy of the referred C bitmap.
+func bitmapCToGo(cbm *C.libxl_bitmap) (bm Bitmap) {
+   // Alloc a Go slice for the bytes
+   size := int(cbm.size)
+   bm.Alloc(size*8)
+
+   // 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(bm.bitmap, mapslice)
+
+   return
+}
+
+func (bm *Bitmap) Test(bit int) (bool) {
+   ubit := uint(bit)
+   if (bit > bm.Max()) {
+   return false
+   }
+   
+   return (bm.bitmap[bit / 8] & (1 << (ubit & 7))) != 0
+}
+
+// FIXME: Do we really just want to silently fail here?
+func (bm *Bitmap) Set(bit int) {
+   ubit := uint(bit)
+   if (bit > bm.Max()) {
+   return
+   }
+   
+   bm.bitmap[bit / 8] |= 1 << (ubit & 7)
+}
+
+func (bm *Bitmap) Clear(bit int) {
+   ubit := uint(bit)
+   if (bit > bm.Max()) {
+   return
+   }
+   
+   bm.bitmap[bit / 8] &= ^(1 << (ubit & 7))
+}
+
+func (bm *Bitmap) Max() (int) {
+   return len(bm.bitmap) * 8
+}
 
 // # Consistent with values defined in domctl.h
 // # Except unknown which we have made up
@@ -222,7 +281,7 @@ type CpupoolInfo struct {
PoolName string
Scheduler Scheduler
DomainCount int
-   // Punt on cpumap for now
+   CpuMap Bitmap
 }
 
 // libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
@@ -248,6 +307,7 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
info.PoolName = C.GoString(cpupoolListSlice[i].pool_name)
info.Scheduler = Scheduler(cpupoolListSlice[i].sched)
info.DomainCount = int(cpupoolListSlice[i].n_dom)
+   info.CpuMap = bitmapCToGo([i].cpumap)
 
list = append(list, info)
}
@@ -268,6 +328,24 @@ func (Ctx *Context) CpupoolFindByName(name string) (info 
CpupoolInfo, found bool
return
 }
 
+// int libxl_cpupool_create(libxl_ctx *ctx, const char *name,
+//  libxl_scheduler sched,
+//  libxl_bitmap cpumap, libxl_uuid *uuid,
+//  uint32_t *poolid);
+// int libxl_cpupool_destroy(libxl_ctx *ctx, uint32_t poolid);
+// int libxl_cpupool_rename(libxl_ctx *ctx, const char *name, uint32_t poolid);
+// int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu);
+// int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
+// int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
+// const libxl_bitmap *cpumap);
+// int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu);
+// int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
+// int libxl_cpupool_cpuremove_cpumap(libxl_ctx *ctx, uint32_t poolid,
+//const libxl_bitmap *cpumap);
+// int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t 
domid);
+// int libxl_cpupool_info(libxl_ctx *ctx, libxl_cpupoolinfo *info, uint32_t 
poolid);
+
+   
 func XlTest(Args []string) {
var Ctx Context
 
@@ -290,7 +368,21 @@ func XlTest(Args []string) {
fmt.Printf("Error: %v\n", err)
}
 
-   fmt.Printf("a: %d b: %s c: %d\n", a, b, int(c)) 
+ 

[Xen-devel] [PATCH RFC 14/59] benchmark: Store data in terms of worker sets and worker ids

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

...rather than having a single global index, in preparation for
summarizing sets of workers as well as individual workers.

To do this:

- Define a WorkerId type which consists of the worker set + worker id
  within that set.  Pass this to the workers and use this in the
  report values.

- Use maps based on this WorkerId for currently running processes,
  accumulated data, and (for now) the results summary.

In a future patch, we'll break down the results summary by worker sets
as well.

Signed-off-by: George Dunlap 
---
 benchmark.go | 120 +++
 processworker.go |   4 +-
 xenworker.go |   6 +--
 3 files changed, 63 insertions(+), 67 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 2a78d26..4354a47 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -33,8 +33,17 @@ type WorkerSummary struct {
MinTput float64
 }
 
-type WorkerReport struct {
+type WorkerId struct {
+   Set int
Id int
+}
+
+func (wid WorkerId) String() (string) {
+   return fmt.Sprintf("%d:%d", wid.Set, wid.Id)
+}
+
+type WorkerReport struct {
+   Id WorkerId
Now int
Mops int
MaxDelta int
@@ -50,7 +59,7 @@ type WorkerSet struct {
 }
 
 type Worker interface {
-   SetId(int)
+   SetId(WorkerId)
Init(WorkerParams) error
Shutdown()
Process(chan WorkerReport, chan bool)
@@ -86,13 +95,13 @@ func Report(ws *WorkerState, r WorkerReport) {
 
tput := Throughput(lr.Now, lr.Mops, r.Now, r.Mops)

-   fmt.Printf("%d Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
+   fmt.Printf("%v Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
}
 
ws.LastReport = r
 }
 
-type WorkerList []WorkerState
+type WorkerList map[WorkerId]*WorkerState
 
 func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
i = 0
@@ -114,41 +123,44 @@ const (
WorkerXen = iota
 )
 
-func NewWorkerList(workers []WorkerSet, workerType int) (ws WorkerList, err 
error) {
-   count := 0
+func NewWorkerList(workers []WorkerSet, workerType int) (wl WorkerList, err 
error) {
+   wl = WorkerList(make(map[WorkerId]*WorkerState))
 
-   // wsi: WorkerSet index
for wsi := range workers {
-   count += workers[wsi].Count
-   }
+   for i := 0; i < workers[wsi].Count; i = i+1 {
+   Id := WorkerId{Set:wsi,Id:i}
 
-   fmt.Println("Making ", count, " total workers")
-   ws = WorkerList(make([]WorkerState, count))
+   ws := wl[Id]
 
-   // wli: WorkerList index
-   wli := 0
-   for wsi := range workers {
-   for i := 0; i < workers[wsi].Count; i, wli = i+1, wli+1 {
+   if ws != nil {
+   panic("Duplicate worker for id!")
+   }
+   
+   ws = {}
+   
switch workerType {
case WorkerProcess:
-   ws[wli].w = {}
+   ws.w = {}
case WorkerXen:
-   ws[wli].w = {}
+   ws.w = {}
default:
err = fmt.Errorf("Unknown type: %d", workerType)
+   return
}
-   ws[wli].w.SetId(wli)
+   
+   ws.w.SetId(Id)

-   ws[wli].w.Init(workers[wsi].Params)
+   ws.w.Init(workers[wsi].Params)
+
+   wl[Id] = ws
}
}
return
 }
 
 type BenchmarkRunData struct {
-   WorkerCount int
Raw []WorkerReport   `json:",omitempty"`
-   Summary []WorkerSummary  `json:",omitempty"`
+   Summary map[WorkerId]*WorkerSummary  `json:",omitempty"`
 }
 
 type BenchmarkRun struct {
@@ -174,8 +186,6 @@ func (run *BenchmarkRun) Run() (err error) {

i := Workers.Start(report, done)
 
-   run.Results.WorkerCount = i
-
// FIXME:
// 1. Make a zero timeout mean "never"
// 2. Make the signals / timeout thing a bit more rational; signal then 
timeout shouldn't hard kill
@@ -185,7 +195,7 @@ func (run *BenchmarkRun) Run() (err error) {
select {
case r := <-report:
run.Results.Raw = append(run.Results.Raw, r)
-   Report([r.Id], r)
+   Report(Workers[r.Id], r)
case <-done:
i--;
fmt.Println(i, "workers left");
@@ -215,22 +225,11 @@ func (run *BenchmarkRun) Run() (err error) {
 }
 
 func (run 

[Xen-devel] [PATCH RFC 51/59] controller: Make and/or modify cpupools when possible

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Make it possible for schedbench to modify cpupools in order to satisfy
run constraints.

Make a "RunConfig" option which contains the name of the pool, the
scheduler, and the number of cpus.  As with WorkerConfig, make these
automatically inherited from larger levels to smaller levels.  This
makes it straightforward to allow arbitrary pool configurations in the
same plan.

Modify sample.bench to have a RunConfig entry at the top level
(instead of the WorkerConfig option).  SimplePlan already sets
RunConfig.Scheduler, so the effect will be for each run to have all
three options set.  (Punt on SimplePlan generating more complex
options for now.)

Change BenchmarkRun.Ready() to BenchmarkRun.Prep(), which will cause
the configuration in RunConfig to become true if possible.  Empty
'Pool' element means the default pool (Pool-0).  Always create the
cpupool if it's non-pool-0, destroying the current one if it exists.

If it is pool 0, just check if it matches, and skip if not.

(We could in theory modify cpupool 0, but push that for future work.)

Signed-off-by: George Dunlap 
---
 benchmark.go |  17 +-
 run.go   | 176 +++
 2 files changed, 169 insertions(+), 24 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index aecb574..bd513fd 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -67,7 +67,6 @@ func (l *WorkerConfig) PropagateFrom(g WorkerConfig) {
}
 }
 
-
 type WorkerSet struct {
Params WorkerParams
Config WorkerConfig
@@ -140,6 +139,21 @@ type BenchmarkRunData struct {
 
 type RunConfig struct {
Scheduler string
+   Pool string
+   Cpus []int
+}
+
+// Propagate unset values from a higher level
+func (l *RunConfig) PropagateFrom(g RunConfig) {
+   if l.Pool == "" {
+   l.Pool = g.Pool
+   }
+   if l.Scheduler == "" {
+   l.Scheduler = g.Scheduler
+   }
+   if l.Cpus == nil {
+   l.Cpus = g.Cpus
+   }
 }
 
 type BenchmarkRun struct {
@@ -159,6 +173,7 @@ type BenchmarkPlan struct {
// Global options for workers that will be over-ridden by Run
// and WorkerSet config options
WorkerConfig `json:",omitempty"`
+   RunConfig RunConfig   `json:",omitempty"`
Runs []BenchmarkRun  `json:",omitempty"`
 }
 
diff --git a/run.go b/run.go
index 1a753bc..2d0db01 100644
--- a/run.go
+++ b/run.go
@@ -156,34 +156,158 @@ func getCpuHz() (err error) {
return
 }
 
-func (run *BenchmarkRun) Ready() (ready bool, why string) {
-   // FIXME: Check WorkerType
-   // Skip this run if it's not the scheduler we want
-   if run.RunConfig.Scheduler != "" {
-   var pool CpupoolInfo
-   if run.WorkerConfig.Pool != "" {
-   var found bool
-   pool, found = 
Ctx.CpupoolFindByName(run.WorkerConfig.Pool)
-   if !found {
-   why = "cpupool error"
-   return
-   }
-   } else {
-   // xl defaults to cpupool 0
-   plist := Ctx.ListCpupool()
-   if len(plist) > 0 {
-   pool = plist[0]
+// If the pool is specified, use that pool; otherwise assume pool 0.
+//
+// Unspecified schedulers match any pool; unspecifiend cpu lists match
+// any pool.
+//
+// If the pool exists and the scheduler and cpu lists match the pool,
+// carry on.  (This is running the VMs in a pre-configured pool.)
+//
+// If the pool exists and either the scheduler or the cpus don't match
+// the pool, and this is pool 0, skip.
+//
+// TODO: If the scheduler matches but the cpus don't, modify the pool
+// by adding or removing cpus.  (This can be done for Pool-0 as well.)
+//
+// If the pool is not Pool-0, and the scheduler doesn't match or the
+// pool doesn't exist, but there are no cpus, skip (because we don't
+// have enough information to create the pool).
+//
+// If the pool is not Pool-0, and either the scheduler or the cpus
+// don't match, and the cpus are specified, create the pool.
+func (run *BenchmarkRun) Prep() (ready bool, why string) {
+   var pool CpupoolInfo
+   poolPresent := false
+   
+   // Generate the requested cpumap
+   var Cpumap Bitmap
+   if run.RunConfig.Cpus != nil {
+   fmt.Print("Run.Prep: Cpus: ")
+   printed := false
+   for _, i := range run.RunConfig.Cpus {
+   if printed {
+   fmt.Printf(",%d", i)
} else {
-   why = "cpupool error"
-   return
+   printed = true
+   fmt.Printf("%d", i)
+   }   
+

[Xen-devel] [PATCH RFC 32/59] controller: Allow specification of an input file

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

So that we can analyze data later if we want.

Signed-off-by: George Dunlap 
---
 main.go | 194 +++-
 1 file changed, 106 insertions(+), 88 deletions(-)

diff --git a/main.go b/main.go
index f8d77cf..ddb768c 100644
--- a/main.go
+++ b/main.go
@@ -26,101 +26,119 @@ import (
 )
 
 func main() {
-   filename := "test.bench"
-
-   switch(os.Args[1]) {
-   case "plan":
-   workerA := []string{"burnwait", "70", "20"}
-   //workerB := []string{"burnwait", "10", "2000"}
-   workerB := []string{"burnwait", "10", "30",
-   "burnwait", "20", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "10", "30",
-   "burnwait", "30", "30",
-   }
+   Args := os.Args
 
+   Args = Args[1:]
+   filename := "test.bench"
 
-   plan :=  BenchmarkPlan{
-   WorkerType:WorkerXen,
-   WorkerConfig:WorkerConfig{Pool:"schedbench"},
-   filename:filename,
-   Runs:[]BenchmarkRun{
-   {Label:"baseline-a",
+   for len(Args) > 0 {
+   switch(Args[0]) {
+   case "-f":
+   if len(Args) < 2 {
+   fmt.Println("Need arg for -f")
+   os.Exit(1)
+   }
+   filename = Args[1]
+   Args = Args[2:]
+   case "plan":
+   workerA := []string{"burnwait", "70", "20"}
+   //workerB := []string{"burnwait", "10", "2000"}
+   workerB := []string{"burnwait", "10", "30",
+   "burnwait", "20", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "30", "30",
+   }
+   
+   
+   plan :=  BenchmarkPlan{
+   WorkerType:WorkerXen,
+   WorkerConfig:WorkerConfig{Pool:"schedbench"},
+   filename:filename,
+   Runs:[]BenchmarkRun{
+   {Label:"baseline-a",
+   WorkerSets:[]WorkerSet{
+   
{Params:WorkerParams{workerA},
+   Count:1}},
+   RuntimeSeconds:10,},
+   {Label:"baseline-b",
+   WorkerSets:[]WorkerSet{
+   
{Params:WorkerParams{workerB},
+   Count:1}},
+   RuntimeSeconds:10,},
+   }}
+   
+   for i := 1; i <= 16 ; i *= 2 {
+   label := fmt.Sprintf("%da+%db", i, i)
+   run := BenchmarkRun{
+   Label:label,
WorkerSets:[]WorkerSet{
{Params:WorkerParams{workerA},
-   Count:1}},
-   RuntimeSeconds:10,},
-   {Label:"baseline-b",
-   WorkerSets:[]WorkerSet{
+   Count:i},
{Params:WorkerParams{workerB},
-   Count:1}},
-   RuntimeSeconds:10,},
-   }}
-
-   for i := 1; i <= 16 ; i *= 2 {
-   label := fmt.Sprintf("%da+%db", i, i)
-   run := BenchmarkRun{
-   Label:label,
-   WorkerSets:[]WorkerSet{
-   {Params:WorkerParams{workerA},
-   Count:i},
-   {Params:WorkerParams{workerB},
-   Count:i}},
-   

[Xen-devel] [PATCH RFC 36/59] controller: Make 'dummy' at the level of 'run' rather than xenworker

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Get rid of xenworker_dummy.go and use stubs.go instead.  This is much
cleaner (as evidenced by the size of the file), and allows us to use
libxl-based things in run.go without having to make a load of dummy
libxl stub functions.

Signed-off-by: George Dunlap 
---
 Makefile   |  2 +-
 stubs.go   | 34 
 xenworker_dummy.go | 58 --
 3 files changed, 35 insertions(+), 59 deletions(-)
 create mode 100644 stubs.go
 delete mode 100644 xenworker_dummy.go

diff --git a/Makefile b/Makefile
index af55e0a..0e0b231 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ schedbench: main.go processworker.go xenworker.go 
benchmark.go run.go libxl.go h
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
 
 # FIXME: Do with dlopen instead
-schedbench-report: main.go processworker.go xenworker_dummy.go benchmark.go 
run.go htmlreport.go plan.go
+schedbench-report: main.go benchmark.go stubs.go htmlreport.go plan.go
go build -o $@ $^
 
 .PHONY: clean
diff --git a/stubs.go b/stubs.go
new file mode 100644
index 000..78987ad
--- /dev/null
+++ b/stubs.go
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+package main
+
+import (
+   "fmt"
+)
+
+func (plan *BenchmarkPlan) Run() (err error) {
+   err = fmt.Errorf("Not implemented")
+
+   return
+}
+
+func XlTest(Args []string) {
+   return
+}
+
diff --git a/xenworker_dummy.go b/xenworker_dummy.go
deleted file mode 100644
index e2dbdae..000
--- a/xenworker_dummy.go
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License only.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-package main
-
-import (
-   "fmt"
-   "io"
-)
-
-type XenWorker struct {
-}
-
-func XlTest(Args []string) {
-   return
-}
-
-func (w *XenWorker) SetId(i WorkerId) {
-}
-
-func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) (err error) {
-   err = fmt.Errorf("Xen functionality not implemented");
-   return
-}
-
-// FIXME: Return an error
-func (w *XenWorker) Shutdown() {
-   
-   return
-}
-
-func (w *XenWorker) DumpLog(f io.Writer) (err error) {
-   err = fmt.Errorf("Xen functionality not implemented");
-   return
-}
-
-
-
-// FIXME: Return an error
-func (w *XenWorker) Process(report chan WorkerReport, done chan WorkerId) {
-   return;
-}
-
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 33/59] controller: Add verbosity argument and update README with new instructions

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 main.go | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/main.go b/main.go
index ddb768c..2aa8bae 100644
--- a/main.go
+++ b/main.go
@@ -30,6 +30,7 @@ func main() {
 
Args = Args[1:]
filename := "test.bench"
+   verbosity := 0
 
for len(Args) > 0 {
switch(Args[0]) {
@@ -40,6 +41,13 @@ func main() {
}
filename = Args[1]
Args = Args[2:]
+   case "-v":
+   if len(Args) < 2 {
+   fmt.Println("Need arg for -v")
+   os.Exit(1)
+   }
+   verbosity, _ = strconv.Atoi(Args[1])
+   Args = Args[2:]
case "plan":
workerA := []string{"burnwait", "70", "20"}
//workerB := []string{"burnwait", "10", "2000"}
@@ -105,12 +113,7 @@ func main() {
Args = Args[1:]

case "report":
-   verbosity := 0
Args = Args[1:]
-   if len(Args) > 0 {
-   verbosity, _ = strconv.Atoi(os.Args[0])
-   Args = Args[1:]
-   }
plan, err := LoadBenchmark(filename)
if err != nil {
fmt.Println("Loading benchmark ", filename, " 
", err)
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 27/59] report: Allow report verbosity to be specified

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Take a third argument to control the level of verbosity.

Also add helpful deltas when reporting the raw results.

Signed-off-by: George Dunlap 
---
 benchmark.go | 17 +++--
 main.go  | 11 ---
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index ffecb82..5e35997 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -342,10 +342,23 @@ func (run *BenchmarkRun) TextReport(level int) (err 
error) {
s.AvgUtil, s.MinMaxUtil.Min, 
s.MinMaxUtil.Max)
 
if level >= 2 {
+   var le WorkerReport
for _, e := range s.Raw {
+   var dtime float64
+   var dCputime time.Duration
+   var dKops int
time := float64(e.Now) / SEC
-   fmt.Printf ("   [%8.3f] %8.3f 
%8d %12d\n", time,
-   e.Cputime.Seconds(), 
e.Kops, e.MaxDelta)
+   if e.Now > le.Now {
+   dtime = float64(e.Now - 
le.Now) / SEC
+   dCputime = e.Cputime - 
le.Cputime
+   dKops = e.Kops - le.Kops
+
+   }
+   fmt.Printf ("   [%8.3f] (%8.3f) 
%8.3f (%8.3f) %8d (%8d) %12d\n",
+   time, dtime,
+   e.Cputime.Seconds(), 
dCputime.Seconds(),
+   e.Kops, dKops, 
e.MaxDelta)
+   le = e
}
}
 
diff --git a/main.go b/main.go
index 6eaa39e..13230a7 100644
--- a/main.go
+++ b/main.go
@@ -22,6 +22,7 @@ package main
 import (
"fmt"
"os"
+   "strconv"
 )
 
 func main() {
@@ -29,9 +30,9 @@ func main() {
 
switch(os.Args[1]) {
case "plan":
-   workerA := []string{"burnwait", "7", "2"}
+   workerA := []string{"burnwait", "70", "20"}
//workerB := []string{"burnwait", "10", "2000"}
-   workerB := []string{"burnwait", "100", "300",
+   workerB := []string{"burnwait", "10", "30",
"burnwait", "20", "30",
"burnwait", "10", "30",
"burnwait", "10", "30",
@@ -91,13 +92,17 @@ func main() {
}

case "report":
+   verbosity := 0
+   if len(os.Args) > 2 {
+   verbosity, _ = strconv.Atoi(os.Args[2])
+   }
plan, err := LoadBenchmark(filename)
if err != nil {
fmt.Println("Loading benchmark ", filename, " ", err)
os.Exit(1)
}

-   err = plan.TextReport(0)
+   err = plan.TextReport(verbosity)
if err != nil {
fmt.Println("Running benchmark run:", err)
os.Exit(1)
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 35/59] libxl: Add ListCpupool

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Add libxl bindings for libxl_list_cpupool().

Define the Scheduler type (based on libxl_schedler) with appropriate
constants and string functions.

Punt on the cpumap part of CpupoolInfo for now.

Also create "xltest" command for testing libxl bindings

Signed-off-by: George Dunlap 
---
 libxl.go   | 152 +
 main.go|   5 ++
 xenworker_dummy.go |   4 ++
 3 files changed, 161 insertions(+)

diff --git a/libxl.go b/libxl.go
index 415de7f..5bdabb1 100644
--- a/libxl.go
+++ b/libxl.go
@@ -2,6 +2,7 @@ package main
 
 /*
 #include 
+#include 
 */
 import "C"
 
@@ -128,3 +129,154 @@ func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
}
return
 }
+
+
+// typedef struct {
+// uint32_t size;  /* number of bytes in map */
+// uint8_t *map;
+// } libxl_bitmap;
+// void libxl_bitmap_init(libxl_bitmap *map);
+// void libxl_bitmap_dispose(libxl_bitmap *map);
+
+// # 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 = 0
+   SchedulerSedf Scheduler = 4
+   SchedulerCredit   Scheduler = 5
+   SchedulerCredit2  Scheduler = 6
+   SchedulerArinc653 Scheduler = 7
+   SchedulerRTDS Scheduler = 8
+)
+
+// const char *libxl_scheduler_to_string(libxl_scheduler p);
+// int libxl_scheduler_from_string(const char *s, libxl_scheduler *e);
+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)
+}
+
+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, )
+   if ret != 0 {
+   err = fmt.Errorf("libxl_scheduler_from_string failed: %d", ret)
+   return
+   }
+
+   s = Scheduler(cs)
+
+   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
+   // Punt on cpumap for now
+}
+
+// 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) {
+   var nbPool C.int
+
+   c_cpupool_list := C.libxl_list_cpupool(Ctx.ctx, )
+
+   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 {
+   var info CpupoolInfo
+   
+   info.PoolId = uint32(cpupoolListSlice[i].poolid)
+   info.PoolName = C.GoString(cpupoolListSlice[i].pool_name)
+   info.Scheduler = Scheduler(cpupoolListSlice[i].sched)
+   info.DomainCount = int(cpupoolListSlice[i].n_dom)
+
+   list = append(list, info)
+   }
+
+   return
+}
+
+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 XlTest(Args []string) {
+   var Ctx Context
+
+   err := Ctx.Open()
+   if err != nil {
+   fmt.Printf("Opening context: %v\n", err)
+   return
+   }
+
+   pool, found := Ctx.CpupoolFindByName("schedbench")
+
+   if found {
+   fmt.Printf("%v\n", pool)
+
+   a := int(pool.Scheduler)
+   b := pool.Scheduler.String()
+   c, err  := SchedulerFromString(b)
+
+   if err != nil {
+   fmt.Printf("Error: %v\n", err)
+   }
+
+   fmt.Printf("a: %d b: %s c: %d\n", a, b, int(c)) 
+   } else {
+   fmt.Printf("schedbench not found")
+   }
+
+   pool, found = Ctx.CpupoolFindByName("schedbnch")
+
+   if found {
+   fmt.Printf("%v\n", pool)
+   } else {
+   

[Xen-devel] [PATCH RFC 37/59] libxl.go: Provide a single global context by default

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Provide a single global context by default, Ctx.  Allow this to be
called with Ctx.Open() multiple times (but Close() only once).

Move xenworker.go to use this global context instead; and open it when
starting the benchmark (rather than opening and closing it for every
run, which is effectively what happens now).

Signed-off-by: George Dunlap 
---
 libxl.go | 12 +---
 run.go   |  7 +++
 xenworker.go | 25 +
 3 files changed, 17 insertions(+), 27 deletions(-)

diff --git a/libxl.go b/libxl.go
index 5bdabb1..9477bca 100644
--- a/libxl.go
+++ b/libxl.go
@@ -16,19 +16,17 @@ type Context struct {
ctx *C.libxl_ctx
 }
 
-func NewContext() (Ctx *Context, err error) {
-   Ctx = {}
-   
-   err = Ctx.Open()
-
-   return
-}
+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(), C.LIBXL_VERSION, 0, 
nil)
 
if ret != 0 {
diff --git a/run.go b/run.go
index 1b39730..08a43ff 100644
--- a/run.go
+++ b/run.go
@@ -228,6 +228,13 @@ func (plan *BenchmarkPlan) Run() (err error) {
if err != nil {
return
}
+
+   if plan.WorkerType == WorkerXen {
+   err = Ctx.Open()
+   if err != nil {
+   return
+   }
+   }

for i := range plan.Runs {
r := [i];
diff --git a/xenworker.go b/xenworker.go
index 45e0876..2649392 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -27,13 +27,6 @@ import (
"io"
 )
 
-type xenGlobal struct {
-   Ctx Context
-   count int
-}
-
-var xg xenGlobal
-
 type XenWorker struct {
id WorkerId
Ctx Context
@@ -68,13 +61,9 @@ func (w *XenWorker) SetId(i WorkerId) {
 }
 
 func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) (err error) {
-   if xg.count == 0 {
-   err = xg.Ctx.Open()
-   if err != nil {
-   return
-   }
+   if err != nil {
+   return
}
-   xg.count++

mock := false

@@ -220,11 +209,6 @@ func (w *XenWorker) Shutdown() {
e.Stdout = os.Stdout
e.Stderr = os.Stderr
 
-   xg.count--
-   if xg.count == 0 {
-   defer xg.Ctx.Close()
-   }
-
err := e.Run()
if err != nil {
fmt.Printf("Error destroying domain: %v\n", err)
@@ -249,7 +233,8 @@ func (w *XenWorker) DumpLog(f io.Writer) (err error) {
 // FIXME: Return an error
 func (w *XenWorker) Process(report chan WorkerReport, done chan WorkerId) {
// // xl unpause [vmname]
-   err := xg.Ctx.DomainUnpause(Domid(w.domid))
+   //err := xg.Ctx.DomainUnpause(Domid(w.domid))
+   err := Ctx.DomainUnpause(Domid(w.domid))
if err != nil {
fmt.Printf("Error unpausing domain: %v\n", err)
return
@@ -268,7 +253,7 @@ func (w *XenWorker) Process(report chan WorkerReport, done 
chan WorkerId) {
var r WorkerReport
json.Unmarshal([]byte(s), )
r.Id = w.id
-   di, err := xg.Ctx.DomainInfo(Domid(w.domid))
+   di, err := Ctx.DomainInfo(Domid(w.domid))
// Ignore errors for now
if err == nil {
r.Cputime = di.Cpu_time
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 40/59] controller: Add / update GPL text

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Add it to files which are missing it; clarify the wording regarding
version 2 only in others.

Signed-off-by: George Dunlap 
---
 benchmark.go | 2 +-
 main.go  | 2 +-
 processworker.go | 2 +-
 xenworker.go | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index b77b66b..aecb574 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -3,7 +3,7 @@
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
+ * published by the Free Software Foundation; version 2 of the
  * License only.
  *
  * This program is distributed in the hope that it will be useful, but
diff --git a/main.go b/main.go
index 2f68969..8cbd708 100644
--- a/main.go
+++ b/main.go
@@ -3,7 +3,7 @@
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
+ * published by the Free Software Foundation; version 2 of the
  * License only.
  *
  * This program is distributed in the hope that it will be useful, but
diff --git a/processworker.go b/processworker.go
index 999e76a..8c27f15 100644
--- a/processworker.go
+++ b/processworker.go
@@ -3,7 +3,7 @@
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
+ * published by the Free Software Foundation; version 2 of the
  * License only.
  *
  * This program is distributed in the hope that it will be useful, but
diff --git a/xenworker.go b/xenworker.go
index 2649392..10817b5 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -3,7 +3,7 @@
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
+ * published by the Free Software Foundation; version 2 of the
  * License only.
  *
  * This program is distributed in the hope that it will be useful, but
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 38/59] controller: Allow multiple schedulers in the same benchmark file

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

First, add a RunConfig element to BenchmarkRun, which contains a
(string) name of the scheduler for this run.

Add run.Ready(), which if RunConfig.Scheduler is non-null, will check
to see if the cpupool in which the VMs will run (either
WorkerConfig.Pool or PoolID 0) has the specified scheduler.

Finally, when expanding the SimpleMatrix plan, if
SimpleMatrix.Schedulers is non-emply, add it to the matrix of runs.
Put them next to each other so that it's easy to compare similar runs
on different schedulers.

Refactor schedbench.sh to account for this, and also update the
README.md.

Signed-off-by: George Dunlap 
---
 benchmark.go |  5 +
 plan.go  | 38 +++---
 run.go   | 59 +--
 3 files changed, 81 insertions(+), 21 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 31b3711..b77b66b 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -138,10 +138,15 @@ type BenchmarkRunData struct {
Summary []WorkerSetSummary  `json:",omitempty"`
 }
 
+type RunConfig struct {
+   Scheduler string
+}
+
 type BenchmarkRun struct {
Label string
WorkerSets []WorkerSet
WorkerConfig
+   RunConfig
RuntimeSeconds int
Completed bool
Results BenchmarkRunData 
diff --git a/plan.go b/plan.go
index 2983e78..24c6bd4 100644
--- a/plan.go
+++ b/plan.go
@@ -35,29 +35,42 @@ func (plan *BenchmarkPlan) ExpandInput() (err error) {
WorkerPresets[k] = plan.Input.WorkerPresets[k];
}
 
+   // Use named schedulers, or default to "" (which will use the
+   // current one)
+   var schedulers []string
+   if plan.Input.SimpleMatrix.Schedulers != nil {
+   schedulers = plan.Input.SimpleMatrix.Schedulers
+   } else {
+   schedulers = append(schedulers, "")
+   }
+
// Always do the baselines
for _, wn := range plan.Input.SimpleMatrix.Workers {
wp := WorkerPresets[wn]
-
+   
if wp.Args == nil {
err = fmt.Errorf("Invalid worker preset: %s", wn)
return
}
-
+   
run := BenchmarkRun{
-   Label:wn+" baseline",
WorkerSets:[]WorkerSet{{Params:wp, Count:1}},
RuntimeSeconds:10,
}
-
-   plan.Runs = append(plan.Runs, run)
+   
+   for _, s := range schedulers {
+   fmt.Printf("Making baseline %s run, sched %s\n", wn, s)
+   run.RunConfig.Scheduler = s
+   run.Label = wn+" baseline "+s
+   plan.Runs = append(plan.Runs, run)
+   }
}
-
+   
for _, c := range plan.Input.SimpleMatrix.Count {
run := BenchmarkRun{
RuntimeSeconds:10,
}
-
+   
var label string
for _, wn := range plan.Input.SimpleMatrix.Workers {
wp := WorkerPresets[wn]
@@ -65,14 +78,17 @@ func (plan *BenchmarkPlan) ExpandInput() (err error) {
if label != "" {
label = label+" + "
}
-   label = fmt.Sprintf("%s%s %d", label, wn, c)
+   label = fmt.Sprintf("%s%s %d ", label, wn, c)

ws := WorkerSet{Params:wp, Count:c}
run.WorkerSets = append(run.WorkerSets, ws)
}
-   run.Label = label
-
-   plan.Runs = append(plan.Runs, run)
+   for _, s := range schedulers {
+   fmt.Printf("Making count %d run, sched %s\n", c, s)
+   run.RunConfig.Scheduler = s
+   run.Label = label+s
+   plan.Runs = append(plan.Runs, run)
+   }
}
 
return
diff --git a/run.go b/run.go
index 08a43ff..1a753bc 100644
--- a/run.go
+++ b/run.go
@@ -3,7 +3,7 @@
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
+ * published by the Free Software Foundation; version 2 of the
  * License only.
  *
  * This program is distributed in the hope that it will be useful, but
@@ -156,6 +156,38 @@ func getCpuHz() (err error) {
return
 }
 
+func (run *BenchmarkRun) Ready() (ready bool, why string) {
+   // FIXME: Check WorkerType
+   // Skip this run if it's not the scheduler we want
+   if run.RunConfig.Scheduler != "" {
+   var pool CpupoolInfo
+   if run.WorkerConfig.Pool != "" {
+   

[Xen-devel] [PATCH RFC 53/59] controller: Add WorkerConfig.SoftAffinity

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

If the SoftAffinity is present, pass it as "cpus_soft = ..." in the
config file.

Signed-off-by: George Dunlap 
---
 benchmark.go | 1 +
 xenworker.go | 4 
 2 files changed, 5 insertions(+)

diff --git a/benchmark.go b/benchmark.go
index bd513fd..d5a0ac8 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -58,6 +58,7 @@ func (l *WorkerParams) SetkHZ(kHZ uint64) {
 
 type WorkerConfig struct {
Pool string
+   SoftAffinity string
 }
 
 // Propagate unset values from a higher level
diff --git a/xenworker.go b/xenworker.go
index 10817b5..f2f316f 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -91,6 +91,10 @@ func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) 
(err error) {
fmt.Fprintf(cfg, "pool = '%s'\n", g.Pool)
}
 
+   if g.SoftAffinity != "" {
+   fmt.Fprintf(cfg, "cpus_soft = '%s'\n", g.SoftAffinity)
+   }
+

// xl create -p [filename]
{
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 57/59] tools/blktap2: remove unused inclusion of sys/sysctl.l

2016-12-28 Thread Ronald Rojas
From: Alistair Francis 

That header file is not used. Removing it would avoid build error with
musl libc, which doesn't have that header file.

Signed-off-by: Alistair Francis 
Reviewed-by: Doug Goldstein 
[ wei: rewrote commit message ]
Acked-by: Wei Liu 
---
 tools/blktap2/drivers/block-remus.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tools/blktap2/drivers/block-remus.c 
b/tools/blktap2/drivers/block-remus.c
index 079588d..7401800 100644
--- a/tools/blktap2/drivers/block-remus.c
+++ b/tools/blktap2/drivers/block-remus.c
@@ -54,7 +54,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 52/59] libxl: Implement Bitmap.String()

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Implement Bitmap.String, which will convert a bitmap into a string
parse-able by libxl.

Signed-off-by: George Dunlap 
---
 libxl.go | 59 ++-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/libxl.go b/libxl.go
index bfcaf0d..aa5c01c 100644
--- a/libxl.go
+++ b/libxl.go
@@ -337,6 +337,51 @@ func (a Bitmap) And(b Bitmap) (c Bitmap) {
return
 }
 
+func (bm Bitmap) String() (s string) {
+   lastOnline := false
+   crange := false
+   printed := false
+   var i int
+   /// --x-x-x -> 2,4-8,10
+   /// --x-xxx -> 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
+}
+
 // const char *libxl_scheduler_to_string(libxl_scheduler p);
 func (s Scheduler) String() (string) {
cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
@@ -608,6 +653,18 @@ func (Ctx *Context) CpupoolMakeFree(Cpumap Bitmap) (err 
error) {
 }
 
 func XlTest(Args []string) {
+   var Cpumap Bitmap
+
+   Cpumap.Set(2)
+   Cpumap.SetRange(4, 8)
+   Cpumap.Set(10)
+
+   fmt.Printf("Cpumap: %v\n", Cpumap)
+
+   Cpumap.Set(9)
+
+   fmt.Printf("Cpumap: %v\n", Cpumap)
+
var Ctx Context
 
err := Ctx.Open()
@@ -635,7 +692,7 @@ func XlTest(Args []string) {
}
}
 
-   var Cpumap Bitmap
+   Cpumap = Bitmap{}
 
Cpumap.SetRange(12, 15)
 
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 11/59] Refactor to move towards benchmark "plans" and data analysis

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

A bit of a roll-up of lots of bits.

Signed-off-by: George Dunlap 
---
 Makefile |   4 +-
 benchmark.go | 256 +++
 main.go  | 197 ++---
 3 files changed, 302 insertions(+), 155 deletions(-)
 create mode 100644 benchmark.go

diff --git a/Makefile b/Makefile
index 16af528..7a33cfb 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,10 @@
-BIN = controller
+BIN = schedbench
 BINALL = $(BIN)
 
 .PHONY: all
 all: $(BIN)
 
-controller: main.go processworker.go xenworker.go
+schedbench: main.go processworker.go xenworker.go benchmark.go
go build -o $@ $^
 
 .PHONY: clean
diff --git a/benchmark.go b/benchmark.go
new file mode 100644
index 000..b2b2399
--- /dev/null
+++ b/benchmark.go
@@ -0,0 +1,256 @@
+package main
+
+import (
+   "fmt"
+   "os"
+   "os/signal"
+   "time"
+   "io/ioutil"
+   "encoding/json"
+)
+
+type WorkerReport struct {
+   Id int
+   Now int
+   Mops int
+   MaxDelta int
+}
+
+type WorkerParams struct {
+   Args []string
+}
+
+type WorkerSet struct {
+   Params WorkerParams
+   Count int
+}
+
+type Worker interface {
+   SetId(int)
+   Init(WorkerParams) error
+   Shutdown()
+   Process(chan WorkerReport, chan bool)
+}
+
+const (
+   USEC = 1000
+   MSEC = USEC * 1000
+   SEC = MSEC * 1000
+)
+
+type WorkerState struct {
+   w Worker
+   LastReport WorkerReport
+}
+
+func Report(ws *WorkerState, r WorkerReport) {
+   //fmt.Println(r)
+
+   lr := ws.LastReport
+
+   if (lr.Now > 0) {
+   time := float64(r.Now - lr.Now) / SEC
+   mops := r.Mops - lr.Mops
+
+   tput := float64(mops) / time
+
+   fmt.Printf("%d Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
+   }
+
+   ws.LastReport = r
+}
+
+type WorkerList []WorkerState
+
+func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
+   i = 0
+   for j := range *ws {
+   go (*ws)[j].w.Process(report, done)
+   i++
+   }
+   return
+}
+
+func (ws *WorkerList) Stop() {
+   for i := range *ws {
+   (*ws)[i].w.Shutdown()
+   }
+}
+
+const (
+   WorkerProcess = iota
+   WorkerXen = iota
+)
+
+func NewWorkerList(workers []WorkerSet, workerType int) (ws WorkerList, err 
error) {
+   count := 0
+
+   // wsi: WorkerSet index
+   for wsi := range workers {
+   count += workers[wsi].Count
+   }
+
+   fmt.Println("Making ", count, " total workers")
+   ws = WorkerList(make([]WorkerState, count))
+
+   // wli: WorkerList index
+   wli := 0
+   for wsi := range workers {
+   for i := 0; i < workers[wsi].Count; i, wli = i+1, wli+1 {
+   switch workerType {
+   case WorkerProcess:
+   ws[wli].w = {}
+   case WorkerXen:
+   ws[wli].w = {}
+   default:
+   err = fmt.Errorf("Unknown type: %d", workerType)
+   }
+   ws[wli].w.SetId(wli)
+   
+   ws[wli].w.Init(workers[wsi].Params)
+   }
+   }
+   return
+}
+
+type BenchmarkRunData struct {
+   Raw []WorkerReport
+}
+
+type BenchmarkRun struct {
+   Completed bool
+   Label string
+   Workers []WorkerSet
+   RuntimeSeconds int
+   Results BenchmarkRunData 
+}
+
+func (run *BenchmarkRun) Run() (err error) {
+   Workers, err := NewWorkerList(run.Workers, WorkerProcess)
+   if err != nil {
+   fmt.Println("Error creating workers: %v", err)
+   return
+   }
+   
+   report := make(chan WorkerReport)
+   done := make(chan bool)
+   signals := make(chan os.Signal, 1)
+
+   signal.Notify(signals, os.Interrupt)
+   
+   i := Workers.Start(report, done)
+
+   // FIXME:
+   // 1. Make a zero timeout mean "never"
+   // 2. Make the signals / timeout thing a bit more rational; signal then 
timeout shouldn't hard kill
+   timeout := time.After(time.Duration(run.RuntimeSeconds) * time.Second);
+   stopped := false
+   for i > 0 {
+   select {
+   case r := <-report:
+   run.Results.Raw = append(run.Results.Raw, r)
+   Report([r.Id], r)
+   case <-done:
+   i--;
+   fmt.Println(i, "workers left");
+   case <-timeout:
+   if ! stopped {
+   Workers.Stop()
+   stopped = true
+   run.Completed = true
+   }
+   case 

[Xen-devel] [PATCH RFC 12/59] Basic 'report' functionality

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Go through the raw data and re-calculate throughput for each
timeframe.  Record for each worker the min and max of these; then take
an average over the whole run.

Have the report go through each and show the worker setup, as well as
the avg, min, and max for each worker.

Also default to running Xen again (rather than processes), and clean
up some chattiness wrt starting Xen processes.

Finally, make the "plan" slightly more programmatic, and test a more
"pipelined" testcase.

Signed-off-by: George Dunlap 
---
 benchmark.go | 163 +--
 main.go  |  56 
 xenworker.go |   4 +-
 3 files changed, 205 insertions(+), 18 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index b2b2399..ec62c3d 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -9,6 +9,12 @@ import (
"encoding/json"
 )
 
+type WorkerSummary struct {
+   MaxTput float64
+   AvgTput float64
+   MinTput float64
+}
+
 type WorkerReport struct {
Id int
Now int
@@ -43,6 +49,14 @@ type WorkerState struct {
LastReport WorkerReport
 }
 
+func Throughput(lt int, lm int, t int, m int) (tput float64) {
+   time := float64(t - lt) / SEC
+   mops := m - lm
+   
+   tput = float64(mops) / time
+   return
+}
+
 func Report(ws *WorkerState, r WorkerReport) {
//fmt.Println(r)
 
@@ -52,8 +66,8 @@ func Report(ws *WorkerState, r WorkerReport) {
time := float64(r.Now - lr.Now) / SEC
mops := r.Mops - lr.Mops
 
-   tput := float64(mops) / time
-
+   tput := Throughput(lr.Now, lr.Mops, r.Now, r.Mops)
+   
fmt.Printf("%d Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
}
 
@@ -114,19 +128,21 @@ func NewWorkerList(workers []WorkerSet, workerType int) 
(ws WorkerList, err erro
 }
 
 type BenchmarkRunData struct {
-   Raw []WorkerReport
+   WorkerCount int
+   Raw []WorkerReport   `json:",omitempty"`
+   Summary []WorkerSummary  `json:",omitempty"`
 }
 
 type BenchmarkRun struct {
-   Completed bool
Label string
Workers []WorkerSet
RuntimeSeconds int
+   Completed bool
Results BenchmarkRunData 
 }
 
 func (run *BenchmarkRun) Run() (err error) {
-   Workers, err := NewWorkerList(run.Workers, WorkerProcess)
+   Workers, err := NewWorkerList(run.Workers, WorkerXen)
if err != nil {
fmt.Println("Error creating workers: %v", err)
return
@@ -140,6 +156,8 @@ func (run *BenchmarkRun) Run() (err error) {

i := Workers.Start(report, done)
 
+   run.Results.WorkerCount = i
+
// FIXME:
// 1. Make a zero timeout mean "never"
// 2. Make the signals / timeout thing a bit more rational; signal then 
timeout shouldn't hard kill
@@ -178,8 +196,121 @@ func (run *BenchmarkRun) Run() (err error) {
return
 }
 
+func (run *BenchmarkRun) checkSummary() (done bool, err error) {
+   if run.Results.WorkerCount == 0 {
+   err = fmt.Errorf("Internal error: WorkerCount 0!")
+   return
+   }
+   
+   if len(run.Results.Summary) == run.Results.WorkerCount {
+   done = true
+   return 
+   }
+   
+   if len(run.Results.Summary) != 0 {
+   err = fmt.Errorf("Internal error: len(Summary) %d, len(Workers) 
%d!\n",
+   len(run.Results.Summary), run.Results.WorkerCount)
+   return
+   }
+
+   return
+}
+
+func (run *BenchmarkRun) Process() (err error) {
+   done, err := run.checkSummary()
+   if done || err != nil {
+   return
+   }
+   
+   wcount := run.Results.WorkerCount
+
+   if len(run.Results.Summary) != 0 {
+   err = fmt.Errorf("Internal error: len(Summary) %d, len(Workers) 
%d!\n",
+   len(run.Results.Summary), wcount)
+   return
+   }
+
+   run.Results.Summary = make([]WorkerSummary, wcount)
+
+   // FIXME: Filter out results which started before all have started
+   
+   data := make([]struct{
+   startTime int
+   lastTime int
+   lastMops int}, wcount)
+
+   for i := range run.Results.Raw {
+   e := run.Results.Raw[i]
+   if e.Id > wcount {
+   err = fmt.Errorf("Internal error: id %d > wcount %d", 
e.Id, wcount)
+   return
+   }
+   
+   d := [e.Id]
+   s := [e.Id]
+
+   if d.startTime == 0 {
+   d.startTime = e.Now
+   } else {
+   tput := Throughput(d.lastTime, d.lastMops, e.Now, 
e.Mops)
+   
+   if tput > s.MaxTput {
+   

[Xen-devel] [PATCH RFC 21/59] Report utilization statistics

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Refactor the min/max into a separate type.

Signed-off-by: George Dunlap 
---
 benchmark.go | 119 +--
 run.go   |   4 +-
 2 files changed, 78 insertions(+), 45 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 4b2d805..b0b55c7 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -87,21 +87,45 @@ func Throughput(lt int, lm int, t int, m int) (tput 
float64) {
return
 }
 
+func Utilization(lt int, lct time.Duration, t int, ct time.Duration) (util 
float64) {
+   util = float64(ct - lct) / float64(t - lt)
+   return
+}
+
+type MinMax struct {
+   Min float64
+   Max float64
+}
+
+func (mm *MinMax) Update(x float64) {
+   if x > mm.Max {
+   mm.Max = x
+   }
+   if x < mm.Min || mm.Min == 0 {
+   mm.Min = x
+   }
+}
+
 type WorkerSummary struct {
-   MaxTput float64
+   MinMaxTput MinMax
+   MinMaxUtil MinMax
AvgTput float64
-   MinTput float64
+   AvgUtil float64
 }
 
 type WorkerSetSummary struct {
Workers[]WorkerSummary
TotalTput float64
-   MaxTput   float64
AvgAvgTputfloat64
+   MinMaxTputMinMax
+   MinMaxAvgTput MinMax
AvgStdDevTput float64
-   AvgMaxTputfloat64
-   AvgMinTputfloat64
-   MinTput   float64
+
+   TotalUtil float64
+   MinMaxUtilMinMax
+   MinMaxAvgUtil MinMax
+   AvgAvgUtilfloat64
+   AvgStdDevUtil float64
 }
 
 type BenchmarkRunData struct {
@@ -146,8 +170,10 @@ func (run *BenchmarkRun) Process() (err error) {
 
type Data struct{
startTime int
+   startCputime time.Duration
lastTime int
lastMops int
+   lastCputime time.Duration
}

data := make(map[WorkerId]*Data)
@@ -183,24 +209,19 @@ func (run *BenchmarkRun) Process() (err error) {

if d.startTime == 0 {
d.startTime = e.Now
+   d.startCputime = e.Cputime
} else {
tput := Throughput(d.lastTime, d.lastMops, e.Now, 
e.Mops)
-   
-   if tput > s.MaxTput {
-   s.MaxTput = tput
-   }
-   if tput < s.MinTput || s.MinTput == 0 {
-   s.MinTput = tput
-   }
-   if tput > ws.MaxTput {
-   ws.MaxTput = tput
-   }
-   if tput < ws.MinTput || ws.MinTput == 0 {
-   ws.MinTput = tput
-   }
+   util := Utilization(d.lastTime, d.lastCputime, e.Now, 
e.Cputime)
+
+   s.MinMaxTput.Update(tput)
+   s.MinMaxUtil.Update(util)
+   ws.MinMaxTput.Update(tput)
+   ws.MinMaxUtil.Update(util)
}
d.lastTime = e.Now
d.lastMops = e.Mops
+   d.lastCputime = e.Cputime
}
 
for Id, d := range data {
@@ -208,45 +229,51 @@ func (run *BenchmarkRun) Process() (err error) {
s := [Id.Id]
 
s.AvgTput = Throughput(d.startTime, 0, d.lastTime, d.lastMops)
-   if s.AvgTput > ws.AvgMaxTput {
-   ws.AvgMaxTput = s.AvgTput
-   }
-   if s.AvgTput < ws.AvgMinTput || ws.AvgMinTput == 0 {
-   ws.AvgMinTput = s.AvgTput
-   }
-   
+   s.AvgUtil = Utilization(d.startTime, d.startCputime, 
d.lastTime, d.lastCputime)
+
+   ws.MinMaxAvgTput.Update(s.AvgTput)
+   ws.MinMaxAvgUtil.Update(s.AvgUtil)
}
 
// Calculate the average-of-averages for each set
for set := range run.Results.Summary {
ws := [set]

-   var total float64
+   var totalTput float64
+   var totalUtil float64
var count int
for id := range ws.Workers {
-   total += ws.Workers[id].AvgTput
+   totalTput += ws.Workers[id].AvgTput
+   totalUtil += ws.Workers[id].AvgUtil
count++
}
 
// FIXME -- Is this legit?
-   ws.TotalTput = total
-   ws.AvgAvgTput = total / float64(count)
+   ws.TotalTput = totalTput
+   ws.TotalUtil = totalUtil
+   ws.AvgAvgTput = totalTput / float64(count)
+   ws.AvgAvgUtil = totalUtil / float64(count)
}
 
// Then calculate the standard deviation
for set := range run.Results.Summary {

[Xen-devel] [PATCH RFC 22/59] Use tsc for time rather than rumpkernel clock_gettime()

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

The rumpkernel clock_gettime() drifts drastically when the system is
overloaded.  Switch to using a TSC timesource instead:

* Use tsc_mode='native' in guest config
* Read the host tsc from /proc/cpuinfo when starting a run
* Pass it as an argument to the worker
* Implement now() with rdtsc

The results appear to continue to be accurate even with heavy
overcommitment.

Signed-off-by: George Dunlap 
---
 benchmark.go |  8 
 run.go   | 45 +
 xenworker.go |  1 +
 3 files changed, 54 insertions(+)

diff --git a/benchmark.go b/benchmark.go
index b0b55c7..7ea9aaa 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -48,6 +48,14 @@ type WorkerParams struct {
Args []string
 }
 
+func (l *WorkerParams) SetkHZ(kHZ uint64) {
+   if l.Args[0] == "kHZ" {
+   l.Args[1] = fmt.Sprintf("%d", kHZ)
+   } else {
+   l.Args = append([]string{"kHZ", fmt.Sprintf("%d", kHZ)}, 
l.Args...)
+   }
+}
+
 type WorkerConfig struct {
Pool string
 }
diff --git a/run.go b/run.go
index 2a93405..4222001 100644
--- a/run.go
+++ b/run.go
@@ -23,6 +23,9 @@ import (
"os"
"os/signal"
"time"
+   "regexp"
+   "strconv"
+   "bufio"
 )
 
 type WorkerState struct {
@@ -106,9 +109,45 @@ func NewWorkerList(WorkerSets []WorkerSet, workerType int) 
(wl WorkerList, err e
return
 }
 
+var CpukHZ uint64
+
+func getCpuHz() (err error) {
+   if CpukHZ == 0 {
+   var cpuinfo *os.File
+   cpuinfo, err = os.Open("/proc/cpuinfo")
+   if err != nil {
+   return
+   }
+   re := regexp.MustCompile("^cpu MHz\\s*: ([0-9.]+)$")
+   scanner := bufio.NewScanner(cpuinfo)
+   for scanner.Scan() {
+   s := scanner.Text()
+   m := re.FindStringSubmatch(s)
+   if m != nil {
+   var MHZ float64
+   MHZ, err = strconv.ParseFloat(m[1], 64)
+   if err != nil {
+   return
+   }
+   CpukHZ = uint64(MHZ*1000)
+   break
+   }
+   }
+   if CpukHZ == 0 {
+   err = fmt.Errorf("Couldn't find cpu MHz")
+   return
+   } else {
+   fmt.Println("CpukHZ: ", CpukHZ)
+   
+   }
+   }
+   return
+}
+
 func (run *BenchmarkRun) Run() (err error) {
for wsi := range run.WorkerSets {
run.WorkerSets[wsi].Config.PropagateFrom(run.WorkerConfig)
+   run.WorkerSets[wsi].Params.SetkHZ(CpukHZ)
}

Workers, err := NewWorkerList(run.WorkerSets, WorkerXen)
@@ -164,6 +203,12 @@ func (run *BenchmarkRun) Run() (err error) {
 }
 
 func (plan *BenchmarkPlan) Run() (err error) {
+
+   err = getCpuHz()
+   if err != nil {
+   return
+   }
+   
for i := range plan.Runs {
r := [i];
if ! r.Completed {
diff --git a/xenworker.go b/xenworker.go
index 4077e77..e98c970 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -95,6 +95,7 @@ func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) (err 
error) {
fmt.Fprintf(cfg, "memory = 32\n")
fmt.Fprintf(cfg, "vcpus = 1\n")
fmt.Fprintf(cfg, "on_crash = 'destroy'\n")
+   fmt.Fprintf(cfg, "tsc_mode = 'native'\n")
 
if g.Pool != "" {
fmt.Fprintf(cfg, "pool = '%s'\n", g.Pool)
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 13/59] Add GPL headers / COPYING file (v2 only)

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 benchmark.go | 18 ++
 main.go  | 19 +++
 processworker.go | 18 ++
 xenworker.go | 18 ++
 4 files changed, 73 insertions(+)

diff --git a/benchmark.go b/benchmark.go
index ec62c3d..2a78d26 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
 package main
 
 import (
diff --git a/main.go b/main.go
index 2696810..ebf990f 100644
--- a/main.go
+++ b/main.go
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
 package main
 
 import (
diff --git a/processworker.go b/processworker.go
index cca6c3b..6f70ce1 100644
--- a/processworker.go
+++ b/processworker.go
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
 package main
 
 import (
diff --git a/xenworker.go b/xenworker.go
index 1ed5cf0..7e85032 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2016 George W. Dunlap, Citrix Systems UK Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License only.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
 package main
 
 import (
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 09/59] controller: Refactor creation and stopping of workers into WorkerList methods

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 main.go | 59 ++-
 1 file changed, 42 insertions(+), 17 deletions(-)

diff --git a/main.go b/main.go
index dbd6276..89e9cf3 100644
--- a/main.go
+++ b/main.go
@@ -55,10 +55,43 @@ func Report(ws *WorkerState, r WorkerReport) {
 
 type WorkerList []WorkerState
 
-func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) {
+func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
+   i = 0
+   for j := range *ws {
+   go (*ws)[j].w.Process(report, done)
+   i++
+   }
+   return
+}
+
+func (ws *WorkerList) Stop() {
for i := range *ws {
-   go (*ws)[i].w.Process(report, done)
+   (*ws)[i].w.Shutdown()
+   }
+}
+
+const (
+   WorkerProcess = iota
+   WorkerXen = iota
+)
+
+func NewWorkerList(count int, workerType int) (ws WorkerList, err error) {
+   ws = WorkerList(make([]WorkerState, count))
+
+   for i := 0; i< count; i++ {
+   switch workerType {
+   case WorkerProcess:
+   ws[i].w = {}
+   case WorkerXen:
+   ws[i].w = {}
+   default:
+   err = fmt.Errorf("Unknown type: %d", workerType)
+   }
+   ws[i].w.SetId(i)
+   
+   ws[i].w.Init(WorkerParams{[]string{"burnwait", "20", 
"2000"}})
}
+   return
 }
 
 func main() {
@@ -72,19 +105,13 @@ func main() {
 
signal.Notify(signals, os.Interrupt)

-   i := 0
-
-   Workers := WorkerList(make([]WorkerState, count))
-   
-   for i = 0; i< count; i++ {
-   //Workers[i].w = {}
-   Workers[i].w = {}
-   Workers[i].w.SetId(i)
-   
-   Workers[i].w.Init(WorkerParams{[]string{"burnwait", "20", 
"2000"}})
+   Workers, err := NewWorkerList(count, WorkerProcess)
+   if err != nil {
+   fmt.Println("Error creating workers: %v", err)
+   return
}
-
-   Workers.Start(report, done)
+   
+   i := Workers.Start(report, done)
 
for i > 0 {
select {
@@ -96,9 +123,7 @@ func main() {
case <-signals:
if ! killed {
fmt.Println("SIGINT receieved, shutting down 
workers")
-   for j := range Workers {
-   Workers[j].w.Shutdown()
-   }
+   Workers.Stop()
killed = true
} else {
fmt.Println("Second SIGINT received, exiting 
without cleaning up")
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 17/59] controller: Collect and display statistics on WorkerSets

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Introduce WorkerSetSummary, to contain WorkerSummary's and collect
data for the set.

For now "if false"-out reporting of individual worker averages; we can
add this back in as an option later.

Signed-off-by: George Dunlap 
---
 benchmark.go | 156 +--
 1 file changed, 121 insertions(+), 35 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index aaa4c98..4cc9d61 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -23,14 +23,9 @@ import (
"os"
"io/ioutil"
"encoding/json"
+   "math"
 )
 
-type WorkerSummary struct {
-   MaxTput float64
-   AvgTput float64
-   MinTput float64
-}
-
 type WorkerId struct {
Set int
Id int
@@ -77,9 +72,26 @@ func Throughput(lt int, lm int, t int, m int) (tput float64) 
{
return
 }
 
+type WorkerSummary struct {
+   MaxTput float64
+   AvgTput float64
+   MinTput float64
+}
+
+type WorkerSetSummary struct {
+   Workers[]WorkerSummary
+   TotalTput float64
+   MaxTput   float64
+   AvgAvgTputfloat64
+   AvgStdDevTput float64
+   AvgMaxTputfloat64
+   AvgMinTputfloat64
+   MinTput   float64
+}
+
 type BenchmarkRunData struct {
Raw []WorkerReport   `json:",omitempty"`
-   Summary map[WorkerId]*WorkerSummary  `json:",omitempty"`
+   Summary []WorkerSetSummary  `json:",omitempty"`
 }
 
 type BenchmarkRun struct {
@@ -90,6 +102,12 @@ type BenchmarkRun struct {
Results BenchmarkRunData 
 }
 
+type BenchmarkPlan struct {
+   filename string
+   WorkerType int
+   Runs []BenchmarkRun
+}
+
 func (run *BenchmarkRun) checkSummary() (done bool, err error) {
if run.Results.Summary != nil {
done = true
@@ -105,7 +123,7 @@ func (run *BenchmarkRun) Process() (err error) {
return
}
 
-   run.Results.Summary = make(map[WorkerId]*WorkerSummary)
+   run.Results.Summary = make([]WorkerSetSummary, len(run.WorkerSets))
 
type Data struct{
startTime int
@@ -118,18 +136,32 @@ func (run *BenchmarkRun) Process() (err error) {
// FIXME: Filter out results which started before all have started
for i := range run.Results.Raw {
e := run.Results.Raw[i]
+
+   if e.Id.Set > len(run.Results.Summary) {
+   return fmt.Errorf("Internal error: e.Id.Set %d > 
len(Results.Summary) %d\n",
+   e.Id.Set, len(run.Results.Summary))
+   }

+   if run.Results.Summary[e.Id.Set].Workers == nil {
+   run.Results.Summary[e.Id.Set].Workers = 
make([]WorkerSummary,
+   run.WorkerSets[e.Id.Set].Count)
+   }
+
+   ws := [e.Id.Set]
+   
+   if e.Id.Id > len(ws.Workers) {
+   return fmt.Errorf("Internal error: e.Id.Id %d > 
len(Results.Summary[].Workers) %d\n",
+   e.Id.Id, len(ws.Workers))
+   }
+
+   s := [e.Id.Id]
+
d := data[e.Id]
if d == nil {
d = {}
data[e.Id] = d
}
-   s := run.Results.Summary[e.Id]
-   if s == nil {
-   s = {}
-   run.Results.Summary[e.Id] = s
-   }
-
+   
if d.startTime == 0 {
d.startTime = e.Now
} else {
@@ -141,16 +173,63 @@ func (run *BenchmarkRun) Process() (err error) {
if tput < s.MinTput || s.MinTput == 0 {
s.MinTput = tput
}
+   if tput > ws.MaxTput {
+   ws.MaxTput = tput
+   }
+   if tput < ws.MinTput || ws.MinTput == 0 {
+   ws.MinTput = tput
+   }
}
d.lastTime = e.Now
d.lastMops = e.Mops
}
 
-   for Id := range data {
-   run.Results.Summary[Id].AvgTput = Throughput(data[Id].startTime,
-   0, data[Id].lastTime, data[Id].lastMops)
+   for Id, d := range data {
+   ws := [Id.Set]
+   s := [Id.Id]
+
+   s.AvgTput = Throughput(d.startTime, 0, d.lastTime, d.lastMops)
+   if s.AvgTput > ws.AvgMaxTput {
+   ws.AvgMaxTput = s.AvgTput
+   }
+   if s.AvgTput < ws.AvgMinTput || ws.AvgMinTput == 0 {
+   ws.AvgMinTput = s.AvgTput
+   }
+   
}
-   
+
+   // Calculate the average-of-averages for each set
+   for set := range 

[Xen-devel] [PATCH RFC 03/59] controller: Initial attempt to generalize process / vm creation

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Create a "Worker" interface, and have ProcessWorker implement that
interface.

Rename "Worker" to "WorkerReport" to make room for the interface.

Signed-off-by: George Dunlap 
---
 main.go | 45 +++--
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/main.go b/main.go
index 0cb9f51..034e2f2 100644
--- a/main.go
+++ b/main.go
@@ -11,24 +11,32 @@ import (

 )
 
-type Worker struct {
+type WorkerReport struct {
Id int
-   
-   c *exec.Cmd
+   Now int
+   Mops int
+   MaxDelta int
+}
+
+type Worker interface {
+   SetId(int)
+   Init() error
+   Shutdown()
+   Process(chan WorkerReport, chan bool)
+}
 
+type ProcessWorker struct {
+   id int
+   c *exec.Cmd
stdout io.ReadCloser
-   
jsonStarted bool
 }
 
-type WorkerReport struct {
-   Id int
-   Now int
-   Mops int
-   MaxDelta int
+func (w *ProcessWorker) SetId(i int) {
+   w.id = i
 }
 
-func (w *Worker) Init() (err error) {
+func (w *ProcessWorker) Init() (err error) {
w.c = exec.Command("../worker/worker-proc", "burnwait", "20", 
"2000")
 
w.stdout, err = w.c.StdoutPipe()
@@ -40,11 +48,11 @@ func (w *Worker) Init() (err error) {
return
 }
 
-func (w *Worker) Shutdown() {
+func (w *ProcessWorker) Shutdown() {
w.c.Process.Kill()
 }
 
-func (w *Worker) Process(report chan WorkerReport, done chan bool) {
+func (w *ProcessWorker) Process(report chan WorkerReport, done chan bool) {
w.c.Start()
 
scanner := bufio.NewScanner(w.stdout)
@@ -57,7 +65,7 @@ func (w *Worker) Process(report chan WorkerReport, done chan 
bool) {
if w.jsonStarted {
var r WorkerReport
json.Unmarshal([]byte(s), )
-   r.Id = w.Id
+   r.Id = w.id
report <- r
} else {
if s == "START JSON" {
@@ -79,7 +87,7 @@ const (
 )
 
 type WorkerState struct {
-   Worker
+   w Worker
LastReport WorkerReport
 }
 
@@ -114,11 +122,12 @@ func main() {
Workers := make([]WorkerState, count)

for i = 0; i< count; i++ {
-   Workers[i].Id = i
+   Workers[i].w = {}
+   Workers[i].w.SetId(i)

-   Workers[i].Init()
+   Workers[i].w.Init()

-   go Workers[i].Process(report, done)
+   go Workers[i].w.Process(report, done)
}
 
for i > 0 {
@@ -131,7 +140,7 @@ func main() {
case <-signals:
fmt.Println("SIGINT receieved, shutting down workers")
for j := range Workers {
-   Workers[j].Shutdown()
+   Workers[j].w.Shutdown()
}
}
}
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 19/59] Add basic libxl framework, get domain cpu_time

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Introduce libxl "Context" class with open, close, and dominfo.

Create a global variable in xenworker.go to hold the context; open on
first worker creation, close on last worker destruction.

Add a new element to WorkerReport, Cputime, and print it out.

For now, include hard-coded link to local Xen libraries.  This should
be sorted out at some point.

Signed-off-by: George Dunlap 
---
 Makefile |  13 +--
 benchmark.go |   2 ++
 libxl.go | 116 +++
 run.go   |   2 +-
 xenworker.go |  26 ++
 5 files changed, 156 insertions(+), 3 deletions(-)
 create mode 100644 libxl.go

diff --git a/Makefile b/Makefile
index 2e06f87..54f2ce8 100644
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,17 @@ BINALL = $(BIN)
 .PHONY: all
 all: $(BIN)
 
-schedbench: main.go processworker.go xenworker.go benchmark.go run.go
-   go build -o $@ $^
+
+
+CGO_CFLAGS = -I/build/hg/xen.git/dist/install/usr/local/include
+CGO_LIBS = -lyajl -lxenlight
+
+# FIXME
+XENLIB_PATH ?= /build/hg/xen.git/dist/install/usr/local/lib/
+CGO_LDFLAGS = -L$(XENLIB_PATH) -Wl,-rpath-link=$(XENLIB_PATH) $(CGO_LIBS)
+
+schedbench: main.go processworker.go xenworker.go benchmark.go run.go libxl.go
+   CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o $@ 
$^
 
 .PHONY: clean
 clean:
diff --git a/benchmark.go b/benchmark.go
index 7fa83d2..4b2d805 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -24,6 +24,7 @@ import (
"io/ioutil"
"encoding/json"
"math"
+   "time"
 )
 
 type WorkerId struct {
@@ -40,6 +41,7 @@ type WorkerReport struct {
Now int
Mops int
MaxDelta int
+   Cputime time.Duration
 }
 
 type WorkerParams struct {
diff --git a/libxl.go b/libxl.go
new file mode 100644
index 000..39e47ab
--- /dev/null
+++ b/libxl.go
@@ -0,0 +1,116 @@
+package main
+
+/*
+#include 
+*/
+import "C"
+
+import (
+   "unsafe"
+   "fmt"
+   "time"
+)
+
+type Context struct {
+   ctx *C.libxl_ctx
+}
+
+func NewContext() (Ctx *Context, err error) {
+   Ctx = {}
+   
+   err = Ctx.Open()
+
+   return
+}
+
+func (Ctx *Context) IsOpen() bool {
+   return Ctx.ctx != nil
+}
+
+func (Ctx *Context) Open() (err error) {
+   ret := C.libxl_ctx_alloc(unsafe.Pointer(), C.LIBXL_VERSION, 0, 
nil)
+
+   if ret != 0 {
+   err = fmt.Errorf("Allocating libxl context: %d", ret)
+   }
+   return
+}
+
+func (Ctx *Context) Close() (err error) {
+   ret := C.libxl_ctx_free(unsafe.Pointer(Ctx.ctx))
+   Ctx.ctx = nil
+
+   if ret != 0 {
+   err = fmt.Errorf("Freeing libxl context: %d", ret)
+   }
+   return
+}
+
+type Domid uint32
+
+type MemKB uint64
+
+// FIXME: Use the idl to generate types
+type Dominfo struct {
+   // FIXME: uuid
+   Domid Domid
+   Running   bool
+   Blocked   bool
+   Pausedbool
+   Shutdown  bool
+   Dying bool
+   Never_stopbool
+   
+   Shutdown_reason   int32 // FIXME shutdown_reason enumeration
+   Outstanding_memkb MemKB
+   Current_memkb MemKB
+   Shared_memkb  MemKB
+   Paged_memkb   MemKB
+   Max_memkb MemKB
+   Cpu_time  time.Duration
+   Vcpu_max_id   uint32
+   Vcpu_online   uint32
+   Cpupool   uint32
+   Domain_type   int32 //FIXME libxl_domain_type enumeration
+
+}
+
+func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
+   if Ctx.ctx == nil {
+   err = fmt.Errorf("Context not opened")
+   return
+   }
+
+   
+   var cdi C.libxl_dominfo
+
+   ret := C.libxl_domain_info(Ctx.ctx, unsafe.Pointer(), 
C.uint32_t(Id))
+
+   // FIXME: IsDomainNotPresentError
+   if ret != 0 {
+   err = fmt.Errorf("libxl_domain_info failed: %d", ret)
+   return
+   }
+
+   // FIXME -- use introspection to make this more robust
+   di = {}
+   di.Domid = Domid(cdi.domid)
+   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.Never_stop = bool(cdi.never_stop)
+   di.Shutdown_reason = int32(cdi.shutdown_reason)
+   di.Outstanding_memkb = MemKB(cdi.outstanding_memkb)
+   di.Current_memkb = MemKB(cdi.current_memkb)
+   di.Shared_memkb = MemKB(cdi.shared_memkb)
+   di.Paged_memkb = MemKB(cdi.paged_memkb)
+   di.Max_memkb = MemKB(cdi.max_memkb)
+   di.Cpu_time = time.Duration(cdi.cpu_time)
+   di.Vcpu_max_id = uint32(cdi.vcpu_max_id)
+   di.Vcpu_online = uint32(cdi.vcpu_online)
+   di.Cpupool = uint32(cdi.cpupool)
+   di.Domain_type = int32(cdi.domain_type)
+   return
+}
diff 

[Xen-devel] [PATCH RFC 26/59] Use kops rather than mops

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

1 million operations on my test box takes about 3ms -- meaning the
minimum granularity for how long to burn cpu is far longer than
typical.  Make this kops instead, giving us a minimum granularity of 3us.

Update most of the default workers to have similar patterns but on a
1/100 (nb not 1/1000) scale; with the exception of worker A (1/1000
scale) and the first worker in worker B (1/10 scale).

Also, actually fix the name of the scheduler in the README.

Signed-off-by: George Dunlap 
---
 benchmark.go | 18 +-
 main.go  | 16 
 run.go   |  8 
 3 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 73c5441..ffecb82 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -39,7 +39,7 @@ func (wid WorkerId) String() (string) {
 type WorkerReport struct {
Id WorkerId
Now int
-   Mops int
+   Kops int
MaxDelta int
Cputime time.Duration
 }
@@ -89,9 +89,9 @@ const (
 
 func Throughput(lt int, lm int, t int, m int) (tput float64) {
time := float64(t - lt) / SEC
-   mops := m - lm
+   kops := m - lm

-   tput = float64(mops) / time
+   tput = float64(kops) / time
return
 }
 
@@ -184,7 +184,7 @@ func (run *BenchmarkRun) Process() (err error) {
startTime int
startCputime time.Duration
lastTime int
-   lastMops int
+   lastKops int
lastCputime time.Duration
}

@@ -225,7 +225,7 @@ func (run *BenchmarkRun) Process() (err error) {
d.startTime = e.Now
d.startCputime = e.Cputime
} else {
-   tput := Throughput(d.lastTime, d.lastMops, e.Now, 
e.Mops)
+   tput := Throughput(d.lastTime, d.lastKops, e.Now, 
e.Kops)
util := Utilization(d.lastTime, d.lastCputime, e.Now, 
e.Cputime)
 
s.MinMaxTput.Update(tput)
@@ -234,7 +234,7 @@ func (run *BenchmarkRun) Process() (err error) {
ws.MinMaxUtil.Update(util)
}
d.lastTime = e.Now
-   d.lastMops = e.Mops
+   d.lastKops = e.Kops
d.lastCputime = e.Cputime
}
 
@@ -242,11 +242,11 @@ func (run *BenchmarkRun) Process() (err error) {
ws := [Id.Set]
s := [Id.Id]
 
-   s.TotalTput = d.lastMops
+   s.TotalTput = d.lastKops
s.TotalTime = time.Duration(d.lastTime - d.startTime)
s.TotalCputime = d.lastCputime - d.startCputime

-   s.AvgTput = Throughput(d.startTime, 0, d.lastTime, d.lastMops)
+   s.AvgTput = Throughput(d.startTime, 0, d.lastTime, d.lastKops)
s.AvgUtil = Utilization(d.startTime, d.startCputime, 
d.lastTime, d.lastCputime)
 
ws.MinMaxAvgTput.Update(s.AvgTput)
@@ -345,7 +345,7 @@ func (run *BenchmarkRun) TextReport(level int) (err error) {
for _, e := range s.Raw {
time := float64(e.Now) / SEC
fmt.Printf ("   [%8.3f] %8.3f 
%8d %12d\n", time,
-   e.Cputime.Seconds(), 
e.Mops, e.MaxDelta)
+   e.Cputime.Seconds(), 
e.Kops, e.MaxDelta)
}
}
 
diff --git a/main.go b/main.go
index 61d3949..6eaa39e 100644
--- a/main.go
+++ b/main.go
@@ -29,15 +29,15 @@ func main() {
 
switch(os.Args[1]) {
case "plan":
-   workerA := []string{"burnwait", "1", "2000"}
+   workerA := []string{"burnwait", "7", "2"}
//workerB := []string{"burnwait", "10", "2000"}
-   workerB := []string{"burnwait", "1", "3000",
-   "burnwait", "2", "3000",
-   "burnwait", "1", "3000",
-   "burnwait", "1", "3000",
-   "burnwait", "1", "3000",
-   "burnwait", "1", "3000",
-   "burnwait", "3", "3000",
+   workerB := []string{"burnwait", "100", "300",
+   "burnwait", "20", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "10", "30",
+   "burnwait", "30", "30",
}
 
 
diff --git a/run.go b/run.go
index 259f427..ed1957b 100644
--- a/run.go
+++ b/run.go
@@ -41,15 +41,15 @@ func Report(ws *WorkerState, r WorkerReport) {
if (lr.Now 

[Xen-devel] [PATCH RFC 24/59] report: Lots of changes

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Store raw worker reports in the worker summary for easy printing.

Add "level" argument to textreport to easly switch between different
levels of granularity.

Report total throughput, time, and cputime for workers.

When running, print plain time and aggregate cputime in addition to
deltas.

Signed-off-by: George Dunlap 
---
 benchmark.go | 34 +++---
 main.go  |  2 +-
 run.go   |  7 +--
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 7ea9aaa..73c5441 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -115,8 +115,12 @@ func (mm *MinMax) Update(x float64) {
 }
 
 type WorkerSummary struct {
+   Raw []WorkerReport
MinMaxTput MinMax
MinMaxUtil MinMax
+   TotalTput int
+   TotalTime time.Duration
+   TotalCputime time.Duration
AvgTput float64
AvgUtil float64
 }
@@ -201,7 +205,7 @@ func (run *BenchmarkRun) Process() (err error) {
}
 
ws := [e.Id.Set]
-   
+
if e.Id.Id > len(ws.Workers) {
return fmt.Errorf("Internal error: e.Id.Id %d > 
len(Results.Summary[].Workers) %d\n",
e.Id.Id, len(ws.Workers))
@@ -209,6 +213,8 @@ func (run *BenchmarkRun) Process() (err error) {
 
s := [e.Id.Id]
 
+   s.Raw = append(s.Raw, e)
+   
d := data[e.Id]
if d == nil {
d = {}
@@ -236,6 +242,10 @@ func (run *BenchmarkRun) Process() (err error) {
ws := [Id.Set]
s := [Id.Id]
 
+   s.TotalTput = d.lastMops
+   s.TotalTime = time.Duration(d.lastTime - d.startTime)
+   s.TotalCputime = d.lastCputime - d.startCputime
+   
s.AvgTput = Throughput(d.startTime, 0, d.lastTime, d.lastMops)
s.AvgUtil = Utilization(d.startTime, d.startCputime, 
d.lastTime, d.lastCputime)
 
@@ -287,7 +297,7 @@ func (run *BenchmarkRun) Process() (err error) {
return
 }
 
-func (run *BenchmarkRun) TextReport() (err error) {
+func (run *BenchmarkRun) TextReport(level int) (err error) {
var done bool
done, err = run.checkSummary()
if err != nil {
@@ -320,15 +330,25 @@ func (run *BenchmarkRun) TextReport() (err error) {
ws.MinMaxAvgUtil.Min, ws.MinMaxUtil.Max, 
ws.MinMaxUtil.Min)
}
 
-   if true {
-   fmt.Printf("\n%8s %8s %8s %8s %8s %8s %8s\n", "workerid", 
"tavg", "tmin", "tmax", "uavg", "umin", "umax")
+   if level >= 1 {
+   fmt.Printf("\n%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n", 
"workerid", "toput", "time", "cpu", "tavg", "tmin", "tmax", "uavg", "umin", 
"umax")
for set := range run.Results.Summary {
for id := range run.Results.Summary[set].Workers {
s := run.Results.Summary[set].Workers[id]
-   fmt.Printf("%2d:%2d%8.2f %8.2f %8.2f %8.2f 
%8.2f %8.2f\n",
+   fmt.Printf("%2d:%2d%10d %8.2f %8.2f %8.2f 
%8.2f %8.2f %8.2f %8.2f %8.2f\n",
set, id,
+   s.TotalTput, s.TotalTime.Seconds(), 
s.TotalCputime.Seconds(),
s.AvgTput, s.MinMaxTput.Min, 
s.MinMaxTput.Max,
s.AvgUtil, s.MinMaxUtil.Min, 
s.MinMaxUtil.Max)
+
+   if level >= 2 {
+   for _, e := range s.Raw {
+   time := float64(e.Now) / SEC
+   fmt.Printf ("   [%8.3f] %8.3f 
%8d %12d\n", time,
+   e.Cputime.Seconds(), 
e.Mops, e.MaxDelta)
+   }
+   }
+
}
}
}
@@ -391,7 +411,7 @@ func (plan *BenchmarkPlan) Save() (err error) {
return
 }
 
-func (plan *BenchmarkPlan) TextReport() (err error) {
+func (plan *BenchmarkPlan) TextReport(level int) (err error) {
for i := range plan.Runs {
r := [i]
if ! r.Completed {
@@ -404,7 +424,7 @@ func (plan *BenchmarkPlan) TextReport() (err error) {
return
}
 
-   err = r.TextReport()
+   err = r.TextReport(level)
if err != nil {
return
}
diff --git a/main.go b/main.go
index a931567..bb46dbc 100644
--- a/main.go
+++ b/main.go
@@ -98,7 +98,7 @@ func main() {
os.Exit(1)
}

-   err = plan.TextReport()
+   err = plan.TextReport(2)

[Xen-devel] [PATCH RFC 23/59] run: Don't collect results reported after command to stop guests is issued

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Particularly on heavily-loaded systems, this can lead to skew as some
guests have already stopped processing.

Signed-off-by: George Dunlap 
---
 run.go | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/run.go b/run.go
index 4222001..41408dd 100644
--- a/run.go
+++ b/run.go
@@ -172,9 +172,14 @@ func (run *BenchmarkRun) Run() (err error) {
for i > 0 {
select {
case r := <-report:
-   run.Results.Raw = append(run.Results.Raw, r)
-   Report(Workers[r.Id], r)
+   if ! stopped {
+   run.Results.Raw = append(run.Results.Raw, r)
+   Report(Workers[r.Id], r)
+   }
case <-done:
+   if ! stopped {
+   fmt.Println("WARNING: Worker left early")
+   }
i--;
fmt.Println(i, "workers left");
case <-timeout:
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 18/59] controller: Add cpupool global config

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Define WorkerConfig for worker configuration, add "Pool" as a pool in
which to place the worker (currently implemented in Xen only).

Add WorkerConfig options at the WorkerSet, BenchmarkRun, and
BenchmarkPlan levels; allow local levels to "override" global config
options.

The cpupool must already be defined.

Signed-off-by: George Dunlap 
---
 benchmark.go | 19 ++-
 main.go  |  1 +
 processworker.go |  2 +-
 run.go   | 16 +++-
 xenworker.go |  6 +-
 5 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/benchmark.go b/benchmark.go
index 4cc9d61..7fa83d2 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -46,14 +46,27 @@ type WorkerParams struct {
Args []string
 }
 
+type WorkerConfig struct {
+   Pool string
+}
+
+// Propagate unset values from a higher level
+func (l *WorkerConfig) PropagateFrom(g WorkerConfig) {
+   if l.Pool == "" {
+   l.Pool = g.Pool
+   }
+}
+
+
 type WorkerSet struct {
Params WorkerParams
+   Config WorkerConfig
Count int
 }
 
 type Worker interface {
SetId(WorkerId)
-   Init(WorkerParams) error
+   Init(WorkerParams, WorkerConfig) error
Shutdown()
Process(chan WorkerReport, chan bool)
 }
@@ -97,6 +110,7 @@ type BenchmarkRunData struct {
 type BenchmarkRun struct {
Label string
WorkerSets []WorkerSet
+   WorkerConfig
RuntimeSeconds int
Completed bool
Results BenchmarkRunData 
@@ -105,6 +119,9 @@ type BenchmarkRun struct {
 type BenchmarkPlan struct {
filename string
WorkerType int
+   // Global options for workers that will be over-ridden by Run
+   // and WorkerSet config options
+   WorkerConfig
Runs []BenchmarkRun
 }
 
diff --git a/main.go b/main.go
index f58068f..a931567 100644
--- a/main.go
+++ b/main.go
@@ -43,6 +43,7 @@ func main() {
 
plan :=  BenchmarkPlan{
WorkerType:WorkerXen,
+   WorkerConfig:WorkerConfig{Pool:"schedbench"},
filename:filename,
Runs:[]BenchmarkRun{
{Label:"baseline-a",
diff --git a/processworker.go b/processworker.go
index 5e26d81..f517321 100644
--- a/processworker.go
+++ b/processworker.go
@@ -38,7 +38,7 @@ func (w *ProcessWorker) SetId(i WorkerId) {
w.id = i
 }
 
-func (w *ProcessWorker) Init(p WorkerParams) (err error) {
+func (w *ProcessWorker) Init(p WorkerParams, g WorkerConfig) (err error) {
w.c = exec.Command("./worker-proc", p.Args...)
 
w.stdout, err = w.c.StdoutPipe()
diff --git a/run.go b/run.go
index 762b408..9f1edcf 100644
--- a/run.go
+++ b/run.go
@@ -96,7 +96,7 @@ func NewWorkerList(WorkerSets []WorkerSet, workerType int) 
(wl WorkerList, err e

ws.w.SetId(Id)

-   ws.w.Init(WorkerSets[wsi].Params)
+   ws.w.Init(WorkerSets[wsi].Params, 
WorkerSets[wsi].Config)
 
wl[Id] = ws
}
@@ -105,6 +105,10 @@ func NewWorkerList(WorkerSets []WorkerSet, workerType int) 
(wl WorkerList, err e
 }
 
 func (run *BenchmarkRun) Run() (err error) {
+   for wsi := range run.WorkerSets {
+   run.WorkerSets[wsi].Config.PropagateFrom(run.WorkerConfig)
+   }
+   
Workers, err := NewWorkerList(run.WorkerSets, WorkerXen)
if err != nil {
fmt.Println("Error creating workers: %v", err)
@@ -159,14 +163,16 @@ func (run *BenchmarkRun) Run() (err error) {
 
 func (plan *BenchmarkPlan) Run() (err error) {
for i := range plan.Runs {
-   if ! plan.Runs[i].Completed {
-   fmt.Printf("Running test [%d] %s\n", i, 
plan.Runs[i].Label)
-   err = plan.Runs[i].Run()
+   r := [i];
+   if ! r.Completed {
+   r.WorkerConfig.PropagateFrom(plan.WorkerConfig)
+   fmt.Printf("Running test [%d] %s\n", i, r.Label)
+   err = r.Run()
if err != nil {
return
}
}
-   fmt.Printf("Test [%d] %s completed\n", i, plan.Runs[i].Label)
+   fmt.Printf("Test [%d] %s completed\n", i, r.Label)
err = plan.Save()
if err != nil {
fmt.Println("Error saving: ", err)
diff --git a/xenworker.go b/xenworker.go
index e14676c..4d42e5e 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -58,7 +58,7 @@ func (w *XenWorker) SetId(i WorkerId) {
w.domid = -1 // INVALID DOMID
 }
 
-func (w *XenWorker) Init(p WorkerParams) (err error) {
+func (w *XenWorker) Init(p WorkerParams, g WorkerConfig) (err error) {
mock := false

// Make xl 

[Xen-devel] [PATCH RFC 44/59] libxl: Implement CpupoolCreate

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Implement CpupoolCreate.

For now, follow the lead of "xl cpupool-create", by automatically
generating a new uuid each time a new cpupool is created, and by not
allowing the user to attempt to set the poolid.

This requires us to implement bytmapGotoC, which C-allocates the
appropriate array and copies the Go byte map into it.  This must be
C-allocated because the runtime restricts how Go-allocated structures
can be passed into C function calls.

While we're here, reorganize functions slightly, and change the Bitmap
implementation to automatically extend the array if the size of the
byte array is too small.

Signed-off-by: George Dunlap 
---
 libxl.go | 119 +--
 1 file changed, 85 insertions(+), 34 deletions(-)

diff --git a/libxl.go b/libxl.go
index 3f6ba01..6e17b53 100644
--- a/libxl.go
+++ b/libxl.go
@@ -176,20 +176,38 @@ func (bm *Bitmap) Alloc(max int) {
 }
 
 // Return a Go bitmap which is a copy of the referred C bitmap.
-func bitmapCToGo(cbm *C.libxl_bitmap) (bm Bitmap) {
+func bitmapCToGo(cbm *C.libxl_bitmap) (gbm Bitmap) {
// Alloc a Go slice for the bytes
size := int(cbm.size)
-   bm.Alloc(size*8)
+   gbm.Alloc(size*8)
 
// 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(bm.bitmap, mapslice)
+   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)
+}
+
 func (bm *Bitmap) Test(bit int) (bool) {
ubit := uint(bit)
if (bit > bm.Max()) {
@@ -199,14 +217,13 @@ func (bm *Bitmap) Test(bit int) (bool) {
return (bm.bitmap[bit / 8] & (1 << (ubit & 7))) != 0
 }
 
-// FIXME: Do we really just want to silently fail here?
 func (bm *Bitmap) Set(bit int) {
-   ubit := uint(bit)
-   if (bit > bm.Max()) {
-   return
+   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[bit / 8] |= 1 << (ubit & 7)
+   bm.bitmap[ibit] |= 1 << (uint(bit) & 7)
 }
 
 func (bm *Bitmap) Clear(bit int) {
@@ -234,12 +251,12 @@ func (bm *Bitmap) Max() (int) {
 // ])
 type Scheduler int
 var (
-   SchedulerUnknown  Scheduler = 0
-   SchedulerSedf Scheduler = 4
-   SchedulerCredit   Scheduler = 5
-   SchedulerCredit2  Scheduler = 6
-   SchedulerArinc653 Scheduler = 7
-   SchedulerRTDS Scheduler = 8
+   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);
@@ -315,23 +332,38 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
return
 }
 
-func (Ctx *Context) CpupoolFindByName(name string) (info CpupoolInfo, found 
bool) {
-   plist := Ctx.ListCpupool()
+// 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) {
+   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()
 
-   for i := range plist {
-   if plist[i].PoolName == name {
-   found = true
-   info = plist[i]
-   return
-   }
+   var cbm C.libxl_bitmap
+   bitmapGotoC(Cpumap, )
+   defer C.libxl_bitmap_dispose()
+   
+   ret := C.libxl_cpupool_create(Ctx.ctx, name, 
C.libxl_scheduler(Scheduler),
+   cbm, , )
+   // FIXME: Proper error
+   if ret != 0 {
+  

[Xen-devel] [PATCH RFC 45/59] libxl: Implement Destroy, Add/Remove operations

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Also:

* Implement useful Bitmap operations: SetRange(), ClearRange(),
IsEmpty(), and And().

* Normalize CpupoolInfo element naming.

* Implement CpupoolMakeFree, which will scan through cpupools freeing
  the cpus in the map.

Signed-off-by: George Dunlap 
---
 libxl.go | 187 ++-
 1 file changed, 150 insertions(+), 37 deletions(-)

diff --git a/libxl.go b/libxl.go
index 6e17b53..92064ca 100644
--- a/libxl.go
+++ b/libxl.go
@@ -226,6 +226,12 @@ func (bm *Bitmap) Set(bit int) {
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()) {
@@ -235,10 +241,42 @@ func (bm *Bitmap) Clear(bit int) {
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
 }
 
+func (bm *Bitmap) IsEmpty() (bool) {
+   for i:=0; i 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
+}
+
 // # Consistent with values defined in domctl.h
 // # Except unknown which we have made up
 // libxl_scheduler = Enumeration("scheduler", [
@@ -294,11 +332,11 @@ func SchedulerFromString(name string) (s Scheduler, err 
error) {
 // ], dir=DIR_OUT)
 
 type CpupoolInfo struct {
-   PoolId uint32
+   Poolid uint32
PoolName string
Scheduler Scheduler
DomainCount int
-   CpuMap Bitmap
+   Cpumap Bitmap
 }
 
 // libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
@@ -320,11 +358,11 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
for i := range cpupoolListSlice {
var info CpupoolInfo

-   info.PoolId = uint32(cpupoolListSlice[i].poolid)
+   info.Poolid = uint32(cpupoolListSlice[i].poolid)
info.PoolName = C.GoString(cpupoolListSlice[i].pool_name)
info.Scheduler = Scheduler(cpupoolListSlice[i].sched)
info.DomainCount = int(cpupoolListSlice[i].n_dom)
-   info.CpuMap = bitmapCToGo([i].cpumap)
+   info.Cpumap = bitmapCToGo([i].cpumap)
 
list = append(list, info)
}
@@ -365,15 +403,78 @@ func (Ctx *Context) CpupoolCreate(Name string, Scheduler 
Scheduler, Cpumap Bitma
 }
 
 // int libxl_cpupool_destroy(libxl_ctx *ctx, uint32_t poolid);
-// int libxl_cpupool_rename(libxl_ctx *ctx, const char *name, uint32_t poolid);
+func (Ctx *Context) CpupoolDestroy(Poolid uint32) (err error) {
+   ret := C.libxl_cpupool_destroy(Ctx.ctx, C.uint32_t(Poolid))
+   // FIXME: Proper error
+   if ret != 0 {
+   err = fmt.Errorf("libxl_cpupool_destroy failed: %d", ret)
+   return
+   }
+
+   return
+}
+
 // int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu);
-// int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
+func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) (err error) {
+   ret := C.libxl_cpupool_cpuadd(Ctx.ctx, C.uint32_t(Poolid), C.int(Cpu))
+   // FIXME: Proper error
+   if ret != 0 {
+   err = fmt.Errorf("libxl_cpupool_cpuadd failed: %d", 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) {
+   var cbm C.libxl_bitmap
+   bitmapGotoC(Cpumap, )
+   defer C.libxl_bitmap_dispose()
+   
+   ret := C.libxl_cpupool_cpuadd_cpumap(Ctx.ctx, C.uint32_t(Poolid), )
+   // FIXME: Proper error
+   if ret != 0 {
+   err = fmt.Errorf("libxl_cpupool_cpuadd_cpumap failed: %d", ret)
+   return
+   }
+
+   return
+}
+
 // int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu);
-// int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, 
int *cpus);
+func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu int) (err error) {
+   ret := 

[Xen-devel] [PATCH RFC 25/59] main: Change default workload to something a bit more extreme

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 main.go | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/main.go b/main.go
index bb46dbc..61d3949 100644
--- a/main.go
+++ b/main.go
@@ -29,15 +29,15 @@ func main() {
 
switch(os.Args[1]) {
case "plan":
-   workerA := []string{"burnwait", "20", "2000"}
+   workerA := []string{"burnwait", "1", "2000"}
//workerB := []string{"burnwait", "10", "2000"}
-   workerB := []string{"burnwait", "1", "2000",
-   "burnwait", "2", "2000",
-   "burnwait", "1", "2000",
-   "burnwait", "1", "2000",
-   "burnwait", "1", "2000",
-   "burnwait", "1", "2000",
-   "burnwait", "3", "2000",
+   workerB := []string{"burnwait", "1", "3000",
+   "burnwait", "2", "3000",
+   "burnwait", "1", "3000",
+   "burnwait", "1", "3000",
+   "burnwait", "1", "3000",
+   "burnwait", "1", "3000",
+   "burnwait", "3", "3000",
}
 
 
@@ -58,7 +58,6 @@ func main() {
RuntimeSeconds:10,},
}}
 
-
for i := 1; i <= 16 ; i *= 2 {
label := fmt.Sprintf("%da+%db", i, i)
run := BenchmarkRun{
@@ -98,7 +97,7 @@ func main() {
os.Exit(1)
}

-   err = plan.TextReport(2)
+   err = plan.TextReport(0)
if err != nil {
fmt.Println("Running benchmark run:", err)
os.Exit(1)
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 10/59] controller: First cut at BenchmarkParams

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Struct for configurable worker sets, as well as a set runtime.

Signed-off-by: George Dunlap 
---
 main.go | 75 ++---
 1 file changed, 53 insertions(+), 22 deletions(-)

diff --git a/main.go b/main.go
index 89e9cf3..7fbb60a 100644
--- a/main.go
+++ b/main.go
@@ -4,7 +4,7 @@ import (
"fmt"
"os"
"os/signal"
-   
+   "time"
 )
 
 type WorkerReport struct {
@@ -18,6 +18,16 @@ type WorkerParams struct {
Args []string
 }
 
+type WorkerSet struct {
+   Params WorkerParams
+   Count int
+}
+
+type BenchmarkParams struct {
+   Workers []WorkerSet
+   RuntimeSeconds int
+}
+
 type Worker interface {
SetId(int)
Init(WorkerParams) error
@@ -75,29 +85,53 @@ const (
WorkerXen = iota
 )
 
-func NewWorkerList(count int, workerType int) (ws WorkerList, err error) {
+func NewWorkerList(workers []WorkerSet, workerType int) (ws WorkerList, err 
error) {
+   count := 0
+
+   // wsi: WorkerSet index
+   for wsi := range workers {
+   count += workers[wsi].Count
+   }
+
+   fmt.Println("Making ", count, " total workers")
ws = WorkerList(make([]WorkerState, count))
 
-   for i := 0; i< count; i++ {
-   switch workerType {
-   case WorkerProcess:
-   ws[i].w = {}
-   case WorkerXen:
-   ws[i].w = {}
-   default:
-   err = fmt.Errorf("Unknown type: %d", workerType)
-   }
-   ws[i].w.SetId(i)
+   // wli: WorkerList index
+   wli := 0
+   for wsi := range workers {
+   for i := 0; i < workers[wsi].Count; i, wli = i+1, wli+1 {
+   switch workerType {
+   case WorkerProcess:
+   ws[wli].w = {}
+   case WorkerXen:
+   ws[wli].w = {}
+   default:
+   err = fmt.Errorf("Unknown type: %d", workerType)
+   }
+   ws[wli].w.SetId(wli)

-   ws[i].w.Init(WorkerParams{[]string{"burnwait", "20", 
"2000"}})
+   ws[wli].w.Init(workers[wsi].Params)
+   }
}
return
 }
 
 func main() {
-   killed := false
-   
-   count := 2
+   bp :=  BenchmarkParams{
+   Workers:[]WorkerSet{
+   {Params:WorkerParams{[]string{"burnwait", "20", 
"2000"}},
+   Count:2},
+   {Params:WorkerParams{[]string{"burnwait", "10", 
"3000"}},
+   Count:3},
+   },
+   RuntimeSeconds:5,
+   }
+
+   Workers, err := NewWorkerList(bp.Workers, WorkerProcess)
+   if err != nil {
+   fmt.Println("Error creating workers: %v", err)
+   return
+   }

report := make(chan WorkerReport)
done := make(chan bool)
@@ -105,14 +139,10 @@ func main() {
 
signal.Notify(signals, os.Interrupt)

-   Workers, err := NewWorkerList(count, WorkerProcess)
-   if err != nil {
-   fmt.Println("Error creating workers: %v", err)
-   return
-   }
-   
i := Workers.Start(report, done)
 
+   timeout := time.After(time.Duration(bp.RuntimeSeconds) * time.Second);
+   killed := false
for i > 0 {
select {
case r := <-report:
@@ -121,6 +151,7 @@ func main() {
i--;
fmt.Println(i, "workers left");
case <-signals:
+   case <-timeout:
if ! killed {
fmt.Println("SIGINT receieved, shutting down 
workers")
Workers.Stop()
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 15/59] controller: Move "running" code to a separate file

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Signed-off-by: George Dunlap 
---
 Makefile |   2 +-
 benchmark.go | 153 --
 run.go   | 178 +++
 3 files changed, 179 insertions(+), 154 deletions(-)
 create mode 100644 run.go

diff --git a/Makefile b/Makefile
index 7a33cfb..2e06f87 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ BINALL = $(BIN)
 .PHONY: all
 all: $(BIN)
 
-schedbench: main.go processworker.go xenworker.go benchmark.go
+schedbench: main.go processworker.go xenworker.go benchmark.go run.go
go build -o $@ $^
 
 .PHONY: clean
diff --git a/benchmark.go b/benchmark.go
index 4354a47..2e03fe5 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -21,8 +21,6 @@ package main
 import (
"fmt"
"os"
-   "os/signal"
-   "time"
"io/ioutil"
"encoding/json"
 )
@@ -71,11 +69,6 @@ const (
SEC = MSEC * 1000
 )
 
-type WorkerState struct {
-   w Worker
-   LastReport WorkerReport
-}
-
 func Throughput(lt int, lm int, t int, m int) (tput float64) {
time := float64(t - lt) / SEC
mops := m - lm
@@ -84,80 +77,6 @@ func Throughput(lt int, lm int, t int, m int) (tput float64) 
{
return
 }
 
-func Report(ws *WorkerState, r WorkerReport) {
-   //fmt.Println(r)
-
-   lr := ws.LastReport
-
-   if (lr.Now > 0) {
-   time := float64(r.Now - lr.Now) / SEC
-   mops := r.Mops - lr.Mops
-
-   tput := Throughput(lr.Now, lr.Mops, r.Now, r.Mops)
-   
-   fmt.Printf("%v Time: %2.3f Mops: %d Tput: %4.2f\n", r.Id, time, 
mops, tput);
-   }
-
-   ws.LastReport = r
-}
-
-type WorkerList map[WorkerId]*WorkerState
-
-func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) (i int) {
-   i = 0
-   for j := range *ws {
-   go (*ws)[j].w.Process(report, done)
-   i++
-   }
-   return
-}
-
-func (ws *WorkerList) Stop() {
-   for i := range *ws {
-   (*ws)[i].w.Shutdown()
-   }
-}
-
-const (
-   WorkerProcess = iota
-   WorkerXen = iota
-)
-
-func NewWorkerList(workers []WorkerSet, workerType int) (wl WorkerList, err 
error) {
-   wl = WorkerList(make(map[WorkerId]*WorkerState))
-
-   for wsi := range workers {
-   for i := 0; i < workers[wsi].Count; i = i+1 {
-   Id := WorkerId{Set:wsi,Id:i}
-
-   ws := wl[Id]
-
-   if ws != nil {
-   panic("Duplicate worker for id!")
-   }
-   
-   ws = {}
-   
-   switch workerType {
-   case WorkerProcess:
-   ws.w = {}
-   case WorkerXen:
-   ws.w = {}
-   default:
-   err = fmt.Errorf("Unknown type: %d", workerType)
-   return
-   }
-   
-   ws.w.SetId(Id)
-   
-   ws.w.Init(workers[wsi].Params)
-
-   wl[Id] = ws
-   }
-   }
-   return
-}
-
 type BenchmarkRunData struct {
Raw []WorkerReport   `json:",omitempty"`
Summary map[WorkerId]*WorkerSummary  `json:",omitempty"`
@@ -171,59 +90,6 @@ type BenchmarkRun struct {
Results BenchmarkRunData 
 }
 
-func (run *BenchmarkRun) Run() (err error) {
-   Workers, err := NewWorkerList(run.Workers, WorkerXen)
-   if err != nil {
-   fmt.Println("Error creating workers: %v", err)
-   return
-   }
-   
-   report := make(chan WorkerReport)
-   done := make(chan bool)
-   signals := make(chan os.Signal, 1)
-
-   signal.Notify(signals, os.Interrupt)
-   
-   i := Workers.Start(report, done)
-
-   // FIXME:
-   // 1. Make a zero timeout mean "never"
-   // 2. Make the signals / timeout thing a bit more rational; signal then 
timeout shouldn't hard kill
-   timeout := time.After(time.Duration(run.RuntimeSeconds) * time.Second);
-   stopped := false
-   for i > 0 {
-   select {
-   case r := <-report:
-   run.Results.Raw = append(run.Results.Raw, r)
-   Report(Workers[r.Id], r)
-   case <-done:
-   i--;
-   fmt.Println(i, "workers left");
-   case <-timeout:
-   if ! stopped {
-   Workers.Stop()
-   stopped = true
-   run.Completed = true
-   }
-   case <-signals:
-   if ! stopped {
-

[Xen-devel] [PATCH RFC 20/59] xenworker: Use libxl_domain_unpause rather than forking xl

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Unpause is a time-sensitive operation; use libxl to unpause directly
rather than forking and execing xl for each VM.

Signed-off-by: George Dunlap 
---
 libxl.go | 14 ++
 xenworker.go | 12 ++--
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/libxl.go b/libxl.go
index 39e47ab..415de7f 100644
--- a/libxl.go
+++ b/libxl.go
@@ -114,3 +114,17 @@ func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err 
error) {
di.Domain_type = int32(cdi.domain_type)
return
 }
+
+func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
+   if Ctx.ctx == nil {
+   err = fmt.Errorf("Context not opened")
+   return
+   }
+
+   ret := C.libxl_domain_unpause(Ctx.ctx, C.uint32_t(Id))
+
+   if ret != 0 {
+   err = fmt.Errorf("libxl_domain_unpause failed: %d", ret)
+   }
+   return
+}
diff --git a/xenworker.go b/xenworker.go
index 31af35f..4077e77 100644
--- a/xenworker.go
+++ b/xenworker.go
@@ -232,16 +232,8 @@ func (w *XenWorker) Shutdown() {
 
 // FIXME: Return an error
 func (w *XenWorker) Process(report chan WorkerReport, done chan bool) {
-   mock := false
-   
-   // xl unpause [vmname]
-   args := []string{"xl", "unpause", w.vmname}
-   if mock {
-   args = append([]string{"echo"}, args...)
-   }
-   e := exec.Command(args[0], args[1:]...)
-
-   err := e.Run()
+   // // xl unpause [vmname]
+   err := xg.Ctx.DomainUnpause(Domid(w.domid))
if err != nil {
fmt.Printf("Error unpausing domain: %v\n", err)
return
-- 
2.7.4


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


[Xen-devel] [PATCH RFC 07/59] controller: Introduce basic Xen functionality

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

Rough-and-ready execution of xl commands, but they work, amazingly.

Signed-off-by: George Dunlap 
---
 Makefile |   2 +-
 main.go  |   3 +-
 xenworker.go | 231 +++
 3 files changed, 234 insertions(+), 2 deletions(-)
 create mode 100644 xenworker.go

diff --git a/Makefile b/Makefile
index 332c8d9..16af528 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ BINALL = $(BIN)
 .PHONY: all
 all: $(BIN)
 
-controller: main.go processworker.go
+controller: main.go processworker.go xenworker.go
go build -o $@ $^
 
 .PHONY: clean
diff --git a/main.go b/main.go
index 90388dd..04c8467 100644
--- a/main.go
+++ b/main.go
@@ -75,7 +75,8 @@ func main() {
Workers := WorkerList(make([]WorkerState, count))

for i = 0; i< count; i++ {
-   Workers[i].w = {}
+   //Workers[i].w = {}
+   Workers[i].w = {}
Workers[i].w.SetId(i)

Workers[i].w.Init(WorkerParams{[]string{"burnwait", "20", 
"2000"}})
diff --git a/xenworker.go b/xenworker.go
new file mode 100644
index 000..6023c50
--- /dev/null
+++ b/xenworker.go
@@ -0,0 +1,231 @@
+package main
+
+import (
+   "fmt"
+   "os"
+   "os/exec"
+   "encoding/json"
+   "bufio"
+   "io"
+)
+
+type XenWorker struct {
+   id int
+   vmname string
+   domid int
+   consoleCmd *exec.Cmd
+   console io.ReadCloser
+   jsonStarted bool
+}
+
+// We have to capitalize the element names so that the json class can
+// get access to it; so annotate the elements so they come out lower
+// case
+type RumpRunConfigBlk struct {
+   Source string `json:"source"`
+   Path string   `json:"path"`
+   Fstype string `json:"fstype"` 
+   Mountpoint string `json:"mountpoint"`
+}
+
+type RumpRunConfig struct {
+   Blk RumpRunConfigBlk `json:"blk"`
+   Cmdline string   `json:"cmdline"`
+   Hostname string  `json:"hostname"`
+}
+
+func (w *XenWorker) SetId(i int) {
+   w.id = i
+   w.vmname = fmt.Sprintf("worker-%d", i)
+   w.domid = -1 // INVALID DOMID
+}
+
+func (w *XenWorker) Init(p WorkerParams) (err error) {
+   mock := false
+   
+   // Make xl config file
+   //  name=worker-$(id)
+
+   cfgName := os.TempDir()+"/schedbench-"+w.vmname+".cfg"
+
+   cfg, err := os.Create(cfgName)
+   //defer os.Remove(cfgName)
+
+   if err != nil {
+   fmt.Printf("Error creating configfile %s: %v\n", cfgName, err)
+   return
+   }
+
+   fmt.Fprintf(cfg, "name = '%s'\n", w.vmname)
+   fmt.Fprintf(cfg, "kernel = 'worker-xen.img'\n")
+   fmt.Fprintf(cfg, "memory = 32\n")
+   fmt.Fprintf(cfg, "vcpus = 1\n")
+   fmt.Fprintf(cfg, "on_crash = 'destroy'\n")
+
+   
+   // xl create -p [filename]
+   {
+   args := []string{"xl", "create", "-p", cfgName}
+   if mock {
+   args = append([]string{"echo"}, args...)
+   }
+   e := exec.Command(args[0], args[1:]...)
+   
+   e.Stdout = os.Stdout
+   e.Stderr = os.Stderr
+
+   err = e.Run()
+   if err != nil {
+   fmt.Printf("Error creating domain: %v\n", err)
+   return
+   }
+   }
+
+   // Get domid
+   {
+   var domidString []byte
+   var args []string
+   
+   if mock {
+   args = []string{"echo", "232"}
+   } else {
+   args = []string{"xl", "domid", w.vmname}
+   }
+   e := exec.Command(args[0], args[1:]...)
+
+   domidString, err = e.Output()
+   if err != nil {
+   fmt.Printf("Error getting domid: %v\n", err)
+   return
+   }
+
+   _, err = fmt.Sscanf(string(domidString), "%d\n", )
+   if err != nil {
+   fmt.Printf("Error converting domid: %v\n", err)
+   return
+   }
+
+   fmt.Printf(" %s domid %d\n", w.vmname, w.domid)
+   }
+   
+   // Set xenstore config
+   {
+   rcfg := RumpRunConfig{
+   Blk:RumpRunConfigBlk{Source:"dev",
+   Path:"virtual",
+   Fstype:"kernfs",
+   Mountpoint:"/kern"},
+   Hostname:w.vmname}
+   
+   rcfg.Cmdline = "worker-xen.img"
+   for _, a := range p.Args {
+   rcfg.Cmdline += fmt.Sprintf(" %s", a)
+   }
+
+   var rcfgBytes []byte
+   
+   rcfgBytes, err = json.Marshal(rcfg)
+   

[Xen-devel] [PATCH RFC 05/59] controller: Add WorkerParams argument to Init in Worker interface

2016-12-28 Thread Ronald Rojas
From: George Dunlap 

For now just make it a plain []string; later make it more abstrcted.

Signed-off-by: George Dunlap 
---
 main.go  | 22 +-
 processworker.go |  4 ++--
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/main.go b/main.go
index a4986cf..90388dd 100644
--- a/main.go
+++ b/main.go
@@ -14,9 +14,13 @@ type WorkerReport struct {
MaxDelta int
 }
 
+type WorkerParams struct {
+   Args []string
+}
+
 type Worker interface {
SetId(int)
-   Init() error
+   Init(WorkerParams) error
Shutdown()
Process(chan WorkerReport, chan bool)
 }
@@ -49,6 +53,14 @@ func Report(ws *WorkerState, r WorkerReport) {
ws.LastReport = r
 }
 
+type WorkerList []WorkerState
+
+func (ws *WorkerList) Start(report chan WorkerReport, done chan bool) {
+   for i := range *ws {
+   go (*ws)[i].w.Process(report, done)
+   }
+}
+
 func main() {
count := 2

@@ -60,17 +72,17 @@ func main() {

i := 0
 
-   Workers := make([]WorkerState, count)
+   Workers := WorkerList(make([]WorkerState, count))

for i = 0; i< count; i++ {
Workers[i].w = {}
Workers[i].w.SetId(i)

-   Workers[i].w.Init()
-   
-   go Workers[i].w.Process(report, done)
+   Workers[i].w.Init(WorkerParams{[]string{"burnwait", "20", 
"2000"}})
}
 
+   Workers.Start(report, done)
+
for i > 0 {
select {
case r := <-report:
diff --git a/processworker.go b/processworker.go
index c1d1fd5..806e4d7 100644
--- a/processworker.go
+++ b/processworker.go
@@ -20,8 +20,8 @@ func (w *ProcessWorker) SetId(i int) {
w.id = i
 }
 
-func (w *ProcessWorker) Init() (err error) {
-   w.c = exec.Command("../worker/worker-proc", "burnwait", "20", 
"2000")
+func (w *ProcessWorker) Init(p WorkerParams) (err error) {
+   w.c = exec.Command("../worker/worker-proc", p.Args...)
 
w.stdout, err = w.c.StdoutPipe()
if err != nil {
-- 
2.7.4


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


  1   2   >